refactor(fmod): move all original files into fmod directory
This commit is contained in:
parent
50fb3c6b1c
commit
35569faecc
544 changed files with 0 additions and 0 deletions
BIN
fmod/win32/bin/nasmw.exe
Executable file
BIN
fmod/win32/bin/nasmw.exe
Executable file
Binary file not shown.
480
fmod/win32/lib/wmsdk/include/asferr.h
Executable file
480
fmod/win32/lib/wmsdk/include/asferr.h
Executable file
|
|
@ -0,0 +1,480 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ASFErr.h - definition of ASF HRESULT codes
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
// Microsoft Windows Media Technologies
|
||||
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
// This file is generated by the MC tool from ASFErr.mc
|
||||
//
|
||||
|
||||
#ifndef _ASFERR_H
|
||||
#define _ASFERR_H
|
||||
|
||||
|
||||
#define STATUS_SEVERITY(hr) (((hr) >> 30) & 0x3)
|
||||
|
||||
#ifdef RC_INVOKED
|
||||
#define _ASF_HRESULT_TYPEDEF_(_sc) _sc
|
||||
#else // RC_INVOKED
|
||||
#define _ASF_HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
|
||||
#endif // RC_INVOKED
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Advanced Streaming Format (ASF) Errors (2000 - 2999)
|
||||
//
|
||||
//
|
||||
// Values are 32 bit values layed out as follows:
|
||||
//
|
||||
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
// +---+-+-+-----------------------+-------------------------------+
|
||||
// |Sev|C|R| Facility | Code |
|
||||
// +---+-+-+-----------------------+-------------------------------+
|
||||
//
|
||||
// where
|
||||
//
|
||||
// Sev - is the severity code
|
||||
//
|
||||
// 00 - Success
|
||||
// 01 - Informational
|
||||
// 10 - Warning
|
||||
// 11 - Error
|
||||
//
|
||||
// C - is the Customer code flag
|
||||
//
|
||||
// R - is a reserved bit
|
||||
//
|
||||
// Facility - is the facility code
|
||||
//
|
||||
// Code - is the facility's status code
|
||||
//
|
||||
//
|
||||
// Define the facility codes
|
||||
//
|
||||
#define FACILITY_NS 0xD
|
||||
|
||||
|
||||
//
|
||||
// Define the severity codes
|
||||
//
|
||||
#define STATUS_SEVERITY_WARNING 0x2
|
||||
#define STATUS_SEVERITY_SUCCESS 0x0
|
||||
#define STATUS_SEVERITY_INFORMATIONAL 0x1
|
||||
#define STATUS_SEVERITY_ERROR 0x3
|
||||
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BUFFEROVERRUN
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// An attempt was made to seek or position past the end of a buffer.%0
|
||||
//
|
||||
#define ASF_E_BUFFEROVERRUN _ASF_HRESULT_TYPEDEF_(0xC00D07D0L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BUFFERTOOSMALL
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The supplied input or output buffer was too small.%0
|
||||
//
|
||||
#define ASF_E_BUFFERTOOSMALL _ASF_HRESULT_TYPEDEF_(0xC00D07D1L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BADLANGUAGEID
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The language ID was not found.%0
|
||||
//
|
||||
#define ASF_E_BADLANGUAGEID _ASF_HRESULT_TYPEDEF_(0xC00D07D2L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOPAYLOADLENGTH
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The multiple payload packet is missing the payload length.%0
|
||||
//
|
||||
#define ASF_E_NOPAYLOADLENGTH _ASF_HRESULT_TYPEDEF_(0xC00D07DBL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_TOOMANYPAYLOADS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The packet contains too many payloads.%0
|
||||
//
|
||||
#define ASF_E_TOOMANYPAYLOADS _ASF_HRESULT_TYPEDEF_(0xC00D07DCL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_PACKETCONTENTTOOLARGE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// ASF_E_PACKETCONTENTTOOLARGE
|
||||
//
|
||||
#define ASF_E_PACKETCONTENTTOOLARGE _ASF_HRESULT_TYPEDEF_(0xC00D07DEL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_UNKNOWNPACKETSIZE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// Expecting a fixed packet size but min. and max. are not equal.%0
|
||||
//
|
||||
#define ASF_E_UNKNOWNPACKETSIZE _ASF_HRESULT_TYPEDEF_(0xC00D07E0L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDHEADER
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// ASF_E_INVALIDHEADER
|
||||
//
|
||||
#define ASF_E_INVALIDHEADER _ASF_HRESULT_TYPEDEF_(0xC00D07E2L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOCLOCKOBJECT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The object does not have a valid clock object.%0
|
||||
//
|
||||
#define ASF_E_NOCLOCKOBJECT _ASF_HRESULT_TYPEDEF_(0xC00D07E6L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_UNKNOWNCLOCKTYPE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// ASF_E_UNKNOWNCLOCKTYPE
|
||||
//
|
||||
#define ASF_E_UNKNOWNCLOCKTYPE _ASF_HRESULT_TYPEDEF_(0xC00D07EBL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_OPAQUEPACKET
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// An attempt was made to restore or access an opaque packet.%0
|
||||
//
|
||||
#define ASF_E_OPAQUEPACKET _ASF_HRESULT_TYPEDEF_(0xC00D07EDL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_WRONGVERSION
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// ASF_E_WRONGVERSION
|
||||
//
|
||||
#define ASF_E_WRONGVERSION _ASF_HRESULT_TYPEDEF_(0xC00D07EEL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_OVERFLOW
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// An attempt was made to store a value which was larger than then destination's maximum value.%0
|
||||
//
|
||||
#define ASF_E_OVERFLOW _ASF_HRESULT_TYPEDEF_(0xC00D07EFL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOTFOUND
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The object was not found.%0
|
||||
//
|
||||
#define ASF_E_NOTFOUND _ASF_HRESULT_TYPEDEF_(0xC00D07F0L)
|
||||
|
||||
//
|
||||
// Someone else is using MessageIds 2033 & 2034, so we skip them
|
||||
//
|
||||
// 2033 = NS_E_NOTHING_TO_DO
|
||||
// 2034 = NS_E_NO_MULTICAST
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_OBJECTTOOBIG
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The object is too large to be processed in the requested manner.%0
|
||||
//
|
||||
#define ASF_E_OBJECTTOOBIG _ASF_HRESULT_TYPEDEF_(0xC00D07F3L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_UNEXPECTEDVALUE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// A value was not set as expected.%0
|
||||
//
|
||||
#define ASF_E_UNEXPECTEDVALUE _ASF_HRESULT_TYPEDEF_(0xC00D07F4L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDSTATE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The request is not valid in the object's current state.%0
|
||||
//
|
||||
#define ASF_E_INVALIDSTATE _ASF_HRESULT_TYPEDEF_(0xC00D07F5L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOLIBRARY
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// This object does not have a valid library pointer; it was not properly created or it has been Shutdown().%0
|
||||
//
|
||||
#define ASF_E_NOLIBRARY _ASF_HRESULT_TYPEDEF_(0xC00D07F6L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_ALREADYINITIALIZED
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// This object has already been initialized; the setting cannot be changed.%0
|
||||
//
|
||||
#define ASF_E_ALREADYINITIALIZED _ASF_HRESULT_TYPEDEF_(0xC00D07F7L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDINIT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// This object has not been initialized properly; that operation cannot be performed.%0
|
||||
//
|
||||
#define ASF_E_INVALIDINIT _ASF_HRESULT_TYPEDEF_(0xC00D07F8L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOHEADEROBJECT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The ASF Header object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOHEADEROBJECT _ASF_HRESULT_TYPEDEF_(0xC00D07F9L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NODATAOBJECT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The ASF Data object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NODATAOBJECT _ASF_HRESULT_TYPEDEF_(0xC00D07FAL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOINDEXOBJECT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The ASF Index object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOINDEXOBJECT _ASF_HRESULT_TYPEDEF_(0xC00D07FBL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOSTREAMPROPS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// A Stream Properties object with the correct stream number could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOSTREAMPROPS _ASF_HRESULT_TYPEDEF_(0xC00D07FCL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOFILEPROPS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The File Properties object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOFILEPROPS _ASF_HRESULT_TYPEDEF_(0xC00D07FDL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOLANGUAGELIST
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The Language List object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOLANGUAGELIST _ASF_HRESULT_TYPEDEF_(0xC00D07FEL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOINDEXPARAMETERS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The Index Parameters object could not be found.%0
|
||||
//
|
||||
#define ASF_E_NOINDEXPARAMETERS _ASF_HRESULT_TYPEDEF_(0xC00D07FFL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_UNSUPPORTEDERRORCONCEALMENT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The requested error concealment strategy is not supported by this component.%0
|
||||
//
|
||||
#define ASF_E_UNSUPPORTEDERRORCONCEALMENT _ASF_HRESULT_TYPEDEF_(0xC00D0800L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDFLAGS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The flags for this object or set of objects are not properly set.%0
|
||||
//
|
||||
#define ASF_E_INVALIDFLAGS _ASF_HRESULT_TYPEDEF_(0xC00D0801L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BADDATADESCRIPTOR
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// One or more data descriptors is not properly set.%0
|
||||
//
|
||||
#define ASF_E_BADDATADESCRIPTOR _ASF_HRESULT_TYPEDEF_(0xC00D0802L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BADINDEXINTERVAL
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The index has an invalid time interval (probably zero).%0
|
||||
//
|
||||
#define ASF_E_BADINDEXINTERVAL _ASF_HRESULT_TYPEDEF_(0xC00D0803L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDTIME
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The given time value is not valid.%0
|
||||
//
|
||||
#define ASF_E_INVALIDTIME _ASF_HRESULT_TYPEDEF_(0xC00D0804L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INVALIDINDEX
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The given index value is not valid.%0
|
||||
//
|
||||
#define ASF_E_INVALIDINDEX _ASF_HRESULT_TYPEDEF_(0xC00D0805L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_STREAMNUMBERINUSE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The specified stream number is already in use.%0
|
||||
//
|
||||
#define ASF_E_STREAMNUMBERINUSE _ASF_HRESULT_TYPEDEF_(0xC00D0806L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BADMEDIATYPE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The specified media type does not work with this component.%0
|
||||
//
|
||||
#define ASF_E_BADMEDIATYPE _ASF_HRESULT_TYPEDEF_(0xC00D0807L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_WRITEFAILED
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The object could not be written as specified.%0
|
||||
//
|
||||
#define ASF_E_WRITEFAILED _ASF_HRESULT_TYPEDEF_(0xC00D0808L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOTENOUGHDESCRIPTORS
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The given data unit requires a larger number of descriptors to be fully parsed.%0
|
||||
//
|
||||
#define ASF_E_NOTENOUGHDESCRIPTORS _ASF_HRESULT_TYPEDEF_(0xC00D0809L)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_INDEXBLOCKUNLOADED
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The index entries for the specified index block have been unloaded from memory and are not available.%0
|
||||
//
|
||||
#define ASF_E_INDEXBLOCKUNLOADED _ASF_HRESULT_TYPEDEF_(0xC00D080AL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_NOTENOUGHBANDWIDTH
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The specified bandwidth is not large enough.%0
|
||||
//
|
||||
#define ASF_E_NOTENOUGHBANDWIDTH _ASF_HRESULT_TYPEDEF_(0xC00D080BL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_EXCEEDEDMAXIMUMOBJECTSIZE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The object has exceeded its maximum size.%0
|
||||
//
|
||||
#define ASF_E_EXCEEDEDMAXIMUMOBJECTSIZE _ASF_HRESULT_TYPEDEF_(0xC00D080CL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_BADDATAUNIT
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The given data unit is corrupted, badly formatted, or otherwise not valid.%0
|
||||
//
|
||||
#define ASF_E_BADDATAUNIT _ASF_HRESULT_TYPEDEF_(0xC00D080DL)
|
||||
|
||||
//
|
||||
// MessageId: ASF_E_HEADERSIZE
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// The ASF header has exceeded the specified maximum size.%0
|
||||
//
|
||||
#define ASF_E_HEADERSIZE _ASF_HRESULT_TYPEDEF_(0xC00D080EL)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Advanced Streaming Format (ASF) Success Codes (2000 - 2999)
|
||||
//
|
||||
|
||||
//
|
||||
// MessageId: ASF_S_OPAQUEPACKET
|
||||
//
|
||||
// MessageText:
|
||||
//
|
||||
// ASF_S_OPAQUEPACKET
|
||||
//
|
||||
#define ASF_S_OPAQUEPACKET _ASF_HRESULT_TYPEDEF_(0x000D07F0L)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Advanced Streaming Format (ASF) Warnings (2000 - 2999)
|
||||
//
|
||||
|
||||
|
||||
#endif // _ASFERR_H
|
||||
|
||||
170
fmod/win32/lib/wmsdk/include/drmexternals.h
Executable file
170
fmod/win32/lib/wmsdk/include/drmexternals.h
Executable file
|
|
@ -0,0 +1,170 @@
|
|||
|
||||
|
||||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 6.00.0361 */
|
||||
/* Compiler settings for drmexternals.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
protocol : dce , ms_ext, c_ext, robust
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
VC __declspec() decoration level:
|
||||
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||
*/
|
||||
//@@MIDL_FILE_HEADING( )
|
||||
|
||||
#pragma warning( disable: 4049 ) /* more than 64k source lines */
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif // __RPCNDR_H_VERSION__
|
||||
|
||||
|
||||
#ifndef __drmexternals_h__
|
||||
#define __drmexternals_h__
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
/* header files for imported files */
|
||||
#include "oaidl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
void * __RPC_USER MIDL_user_allocate(size_t);
|
||||
void __RPC_USER MIDL_user_free( void * );
|
||||
|
||||
/* interface __MIDL_itf_drmexternals_0000 */
|
||||
/* [local] */
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// Microsoft Windows Media Technologies
|
||||
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
//=========================================================================
|
||||
static const WCHAR *g_wszWMDRM_RIGHT_PLAYBACK = L"Play";
|
||||
static const WCHAR *g_wszWMDRM_RIGHT_COPY_TO_CD = L"Print.redbook";
|
||||
static const WCHAR *g_wszWMDRM_RIGHT_COPY_TO_SDMI_DEVICE = L"Transfer.SDMI";
|
||||
static const WCHAR *g_wszWMDRM_RIGHT_COPY_TO_NON_SDMI_DEVICE = L"Transfer.NONSDMI";
|
||||
static const WCHAR *g_wszWMDRM_RIGHT_BACKUP = L"Backup";
|
||||
static const WCHAR *g_wszWMDRM_IsDRM = L"IsDRM";
|
||||
static const WCHAR *g_wszWMDRM_IsDRMCached = L"IsDRMCached";
|
||||
static const WCHAR *g_wszWMDRM_BaseLicenseAcqURL = L"BaseLAURL";
|
||||
static const WCHAR *g_wszWMDRM_Rights = L"Rights";
|
||||
static const WCHAR *g_wszWMDRM_LicenseID = L"LID";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed = L"ActionAllowed.";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed_Playback = L"ActionAllowed.Play";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed_CopyToCD = L"ActionAllowed.Print.redbook";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed_CopyToSDMIDevice = L"ActionAllowed.Transfer.SDMI";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed_CopyToNonSDMIDevice = L"ActionAllowed.Transfer.NONSDMI";
|
||||
static const WCHAR *g_wszWMDRM_ActionAllowed_Backup = L"ActionAllowed.Backup";
|
||||
static const WCHAR *g_wszWMDRM_LicenseState = L"LicenseStateData.";
|
||||
static const WCHAR *g_wszWMDRM_LicenseState_Playback = L"LicenseStateData.Play";
|
||||
static const WCHAR *g_wszWMDRM_LicenseState_CopyToCD = L"LicenseStateData.Print.redbook";
|
||||
static const WCHAR *g_wszWMDRM_LicenseState_CopyToSDMIDevice = L"LicenseStateData.Transfer.SDMI";
|
||||
static const WCHAR *g_wszWMDRM_LicenseState_CopyToNonSDMIDevice = L"LicenseStateData.Transfer.NONSDMI";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader = L"DRMHeader.";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_KeyID = L"DRMHeader.KID";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_LicenseAcqURL = L"DRMHeader.LAINFO";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_ContentID = L"DRMHeader.CID";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_IndividualizedVersion = L"DRMHeader.SECURITYVERSION";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_ContentDistributor = L"DRMHeader.ContentDistributor";
|
||||
static const WCHAR *g_wszWMDRM_DRMHeader_SubscriptionContentID = L"DRMHeader.SubscriptionContentID";
|
||||
typedef
|
||||
enum DRM_LICENSE_STATE_CATEGORY
|
||||
{ WM_DRM_LICENSE_STATE_NORIGHT = 0,
|
||||
WM_DRM_LICENSE_STATE_UNLIM = WM_DRM_LICENSE_STATE_NORIGHT + 1,
|
||||
WM_DRM_LICENSE_STATE_COUNT = WM_DRM_LICENSE_STATE_UNLIM + 1,
|
||||
WM_DRM_LICENSE_STATE_FROM = WM_DRM_LICENSE_STATE_COUNT + 1,
|
||||
WM_DRM_LICENSE_STATE_UNTIL = WM_DRM_LICENSE_STATE_FROM + 1,
|
||||
WM_DRM_LICENSE_STATE_FROM_UNTIL = WM_DRM_LICENSE_STATE_UNTIL + 1,
|
||||
WM_DRM_LICENSE_STATE_COUNT_FROM = WM_DRM_LICENSE_STATE_FROM_UNTIL + 1,
|
||||
WM_DRM_LICENSE_STATE_COUNT_UNTIL = WM_DRM_LICENSE_STATE_COUNT_FROM + 1,
|
||||
WM_DRM_LICENSE_STATE_COUNT_FROM_UNTIL = WM_DRM_LICENSE_STATE_COUNT_UNTIL + 1,
|
||||
WM_DRM_LICENSE_STATE_EXPIRATION_AFTER_FIRSTUSE = WM_DRM_LICENSE_STATE_COUNT_FROM_UNTIL + 1
|
||||
} DRM_LICENSE_STATE_CATEGORY;
|
||||
|
||||
typedef struct _DRM_LICENSE_STATE_DATA
|
||||
{
|
||||
DWORD dwStreamId;
|
||||
DRM_LICENSE_STATE_CATEGORY dwCategory;
|
||||
DWORD dwNumCounts;
|
||||
DWORD dwCount[ 4 ];
|
||||
DWORD dwNumDates;
|
||||
FILETIME datetime[ 4 ];
|
||||
DWORD dwVague;
|
||||
} DRM_LICENSE_STATE_DATA;
|
||||
|
||||
typedef
|
||||
enum DRM_HTTP_STATUS
|
||||
{ HTTP_NOTINITIATED = 0,
|
||||
HTTP_CONNECTING = HTTP_NOTINITIATED + 1,
|
||||
HTTP_REQUESTING = HTTP_CONNECTING + 1,
|
||||
HTTP_RECEIVING = HTTP_REQUESTING + 1,
|
||||
HTTP_COMPLETED = HTTP_RECEIVING + 1
|
||||
} DRM_HTTP_STATUS;
|
||||
|
||||
typedef
|
||||
enum DRM_INDIVIDUALIZATION_STATUS
|
||||
{ INDI_UNDEFINED = 0,
|
||||
INDI_BEGIN = 0x1,
|
||||
INDI_SUCCEED = 0x2,
|
||||
INDI_FAIL = 0x4,
|
||||
INDI_CANCEL = 0x8,
|
||||
INDI_DOWNLOAD = 0x10,
|
||||
INDI_INSTALL = 0x20
|
||||
} DRM_INDIVIDUALIZATION_STATUS;
|
||||
|
||||
typedef struct _WMIndividualizeStatus
|
||||
{
|
||||
HRESULT hr;
|
||||
DRM_INDIVIDUALIZATION_STATUS enIndiStatus;
|
||||
LPSTR pszIndiRespUrl;
|
||||
DWORD dwHTTPRequest;
|
||||
DRM_HTTP_STATUS enHTTPStatus;
|
||||
DWORD dwHTTPReadProgress;
|
||||
DWORD dwHTTPReadTotal;
|
||||
} WM_INDIVIDUALIZE_STATUS;
|
||||
|
||||
typedef struct _WMGetLicenseData
|
||||
{
|
||||
DWORD dwSize;
|
||||
HRESULT hr;
|
||||
WCHAR *wszURL;
|
||||
WCHAR *wszLocalFilename;
|
||||
BYTE *pbPostData;
|
||||
DWORD dwPostDataSize;
|
||||
} WM_GET_LICENSE_DATA;
|
||||
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_drmexternals_0000_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_drmexternals_0000_v0_0_s_ifspec;
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
9219
fmod/win32/lib/wmsdk/include/nserror.h
Executable file
9219
fmod/win32/lib/wmsdk/include/nserror.h
Executable file
File diff suppressed because it is too large
Load diff
947
fmod/win32/lib/wmsdk/include/wmsbuffer.h
Executable file
947
fmod/win32/lib/wmsdk/include/wmsbuffer.h
Executable file
|
|
@ -0,0 +1,947 @@
|
|||
|
||||
|
||||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 6.00.0361 */
|
||||
/* Compiler settings for wmsbuffer.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
protocol : dce , ms_ext, c_ext, robust
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
VC __declspec() decoration level:
|
||||
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||
*/
|
||||
//@@MIDL_FILE_HEADING( )
|
||||
|
||||
#pragma warning( disable: 4049 ) /* more than 64k source lines */
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif // __RPCNDR_H_VERSION__
|
||||
|
||||
#ifndef COM_NO_WINDOWS_H
|
||||
#include "windows.h"
|
||||
#include "ole2.h"
|
||||
#endif /*COM_NO_WINDOWS_H*/
|
||||
|
||||
#ifndef __wmsbuffer_h__
|
||||
#define __wmsbuffer_h__
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __INSSBuffer_FWD_DEFINED__
|
||||
#define __INSSBuffer_FWD_DEFINED__
|
||||
typedef interface INSSBuffer INSSBuffer;
|
||||
#endif /* __INSSBuffer_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer2_FWD_DEFINED__
|
||||
#define __INSSBuffer2_FWD_DEFINED__
|
||||
typedef interface INSSBuffer2 INSSBuffer2;
|
||||
#endif /* __INSSBuffer2_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer3_FWD_DEFINED__
|
||||
#define __INSSBuffer3_FWD_DEFINED__
|
||||
typedef interface INSSBuffer3 INSSBuffer3;
|
||||
#endif /* __INSSBuffer3_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer4_FWD_DEFINED__
|
||||
#define __INSSBuffer4_FWD_DEFINED__
|
||||
typedef interface INSSBuffer4 INSSBuffer4;
|
||||
#endif /* __INSSBuffer4_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IWMSBufferAllocator_FWD_DEFINED__
|
||||
#define __IWMSBufferAllocator_FWD_DEFINED__
|
||||
typedef interface IWMSBufferAllocator IWMSBufferAllocator;
|
||||
#endif /* __IWMSBufferAllocator_FWD_DEFINED__ */
|
||||
|
||||
|
||||
/* header files for imported files */
|
||||
#include "objidl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
void * __RPC_USER MIDL_user_allocate(size_t);
|
||||
void __RPC_USER MIDL_user_free( void * );
|
||||
|
||||
/* interface __MIDL_itf_wmsbuffer_0000 */
|
||||
/* [local] */
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// Microsoft Windows Media Technologies
|
||||
// Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
//=========================================================================
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
EXTERN_GUID( IID_INSSBuffer, 0xE1CD3524,0x03D7,0x11d2,0x9E,0xED,0x00,0x60,0x97,0xD2,0xD7,0xCF );
|
||||
EXTERN_GUID( IID_IWMSBuffer, 0xE1CD3524,0x03D7,0x11d2,0x9E,0xED,0x00,0x60,0x97,0xD2,0xD7,0xCF );
|
||||
EXTERN_GUID( IID_INSSBuffer2,0x4f528693,0x1035,0x43fe,0xb4,0x28,0x75,0x75,0x61,0xad,0x3a,0x68 );
|
||||
EXTERN_GUID( IID_INSSBuffer3,0xc87ceaaf,0x75be,0x4bc4,0x84,0xeb,0xac,0x27,0x98,0x50,0x76,0x72 );
|
||||
EXTERN_GUID( IID_INSSBuffer4,0xb6b8fd5a,0x32e2,0x49d4,0xa9,0x10,0xc2,0x6c,0xc8,0x54,0x65,0xed );
|
||||
EXTERN_GUID( IID_IWMSBufferAllocator, 0x61103CA4,0x2033,0x11d2,0x9E,0xF1,0x00,0x60,0x97,0xD2,0xD7,0xCF );
|
||||
#define IWMSBuffer INSSBuffer
|
||||
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_wmsbuffer_0000_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_wmsbuffer_0000_v0_0_s_ifspec;
|
||||
|
||||
#ifndef __INSSBuffer_INTERFACE_DEFINED__
|
||||
#define __INSSBuffer_INTERFACE_DEFINED__
|
||||
|
||||
/* interface INSSBuffer */
|
||||
/* [version][uuid][unique][object][local] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_INSSBuffer;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("E1CD3524-03D7-11d2-9EED-006097D2D7CF")
|
||||
INSSBuffer : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE GetLength(
|
||||
/* [out] */ DWORD *pdwLength) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetLength(
|
||||
/* [in] */ DWORD dwLength) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetMaxLength(
|
||||
/* [out] */ DWORD *pdwLength) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetBuffer(
|
||||
/* [out] */ BYTE **ppdwBuffer) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetBufferAndLength(
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct INSSBufferVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INSSBuffer * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INSSBuffer * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INSSBuffer * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetLength )(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetLength )(
|
||||
INSSBuffer * This,
|
||||
/* [in] */ DWORD dwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMaxLength )(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBuffer )(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ BYTE **ppdwBuffer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBufferAndLength )(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
END_INTERFACE
|
||||
} INSSBufferVtbl;
|
||||
|
||||
interface INSSBuffer
|
||||
{
|
||||
CONST_VTBL struct INSSBufferVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define INSSBuffer_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define INSSBuffer_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define INSSBuffer_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define INSSBuffer_GetLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer_SetLength(This,dwLength) \
|
||||
(This)->lpVtbl -> SetLength(This,dwLength)
|
||||
|
||||
#define INSSBuffer_GetMaxLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetMaxLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer_GetBuffer(This,ppdwBuffer) \
|
||||
(This)->lpVtbl -> GetBuffer(This,ppdwBuffer)
|
||||
|
||||
#define INSSBuffer_GetBufferAndLength(This,ppdwBuffer,pdwLength) \
|
||||
(This)->lpVtbl -> GetBufferAndLength(This,ppdwBuffer,pdwLength)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer_GetLength_Proxy(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer_GetLength_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer_SetLength_Proxy(
|
||||
INSSBuffer * This,
|
||||
/* [in] */ DWORD dwLength);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer_SetLength_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer_GetMaxLength_Proxy(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer_GetMaxLength_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer_GetBuffer_Proxy(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ BYTE **ppdwBuffer);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer_GetBuffer_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer_GetBufferAndLength_Proxy(
|
||||
INSSBuffer * This,
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer_GetBufferAndLength_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __INSSBuffer_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer2_INTERFACE_DEFINED__
|
||||
#define __INSSBuffer2_INTERFACE_DEFINED__
|
||||
|
||||
/* interface INSSBuffer2 */
|
||||
/* [version][uuid][unique][object][local] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_INSSBuffer2;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("4F528693-1035-43fe-B428-757561AD3A68")
|
||||
INSSBuffer2 : public INSSBuffer
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE GetSampleProperties(
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [out] */ BYTE *pbProperties) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetSampleProperties(
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [in] */ BYTE *pbProperties) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct INSSBuffer2Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INSSBuffer2 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INSSBuffer2 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetLength )(
|
||||
INSSBuffer2 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetLength )(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ DWORD dwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMaxLength )(
|
||||
INSSBuffer2 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBuffer )(
|
||||
INSSBuffer2 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBufferAndLength )(
|
||||
INSSBuffer2 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetSampleProperties )(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [out] */ BYTE *pbProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetSampleProperties )(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [in] */ BYTE *pbProperties);
|
||||
|
||||
END_INTERFACE
|
||||
} INSSBuffer2Vtbl;
|
||||
|
||||
interface INSSBuffer2
|
||||
{
|
||||
CONST_VTBL struct INSSBuffer2Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define INSSBuffer2_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define INSSBuffer2_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define INSSBuffer2_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define INSSBuffer2_GetLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer2_SetLength(This,dwLength) \
|
||||
(This)->lpVtbl -> SetLength(This,dwLength)
|
||||
|
||||
#define INSSBuffer2_GetMaxLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetMaxLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer2_GetBuffer(This,ppdwBuffer) \
|
||||
(This)->lpVtbl -> GetBuffer(This,ppdwBuffer)
|
||||
|
||||
#define INSSBuffer2_GetBufferAndLength(This,ppdwBuffer,pdwLength) \
|
||||
(This)->lpVtbl -> GetBufferAndLength(This,ppdwBuffer,pdwLength)
|
||||
|
||||
|
||||
#define INSSBuffer2_GetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> GetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
#define INSSBuffer2_SetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> SetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer2_GetSampleProperties_Proxy(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [out] */ BYTE *pbProperties);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer2_GetSampleProperties_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer2_SetSampleProperties_Proxy(
|
||||
INSSBuffer2 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [in] */ BYTE *pbProperties);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer2_SetSampleProperties_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __INSSBuffer2_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer3_INTERFACE_DEFINED__
|
||||
#define __INSSBuffer3_INTERFACE_DEFINED__
|
||||
|
||||
/* interface INSSBuffer3 */
|
||||
/* [version][uuid][unique][object][local] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_INSSBuffer3;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("C87CEAAF-75BE-4bc4-84EB-AC2798507672")
|
||||
INSSBuffer3 : public INSSBuffer2
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetProperty(
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [in] */ void *pvBufferProperty,
|
||||
/* [in] */ DWORD dwBufferPropertySize) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetProperty(
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct INSSBuffer3Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INSSBuffer3 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INSSBuffer3 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetLength )(
|
||||
INSSBuffer3 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetLength )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ DWORD dwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMaxLength )(
|
||||
INSSBuffer3 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBuffer )(
|
||||
INSSBuffer3 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBufferAndLength )(
|
||||
INSSBuffer3 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetSampleProperties )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [out] */ BYTE *pbProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetSampleProperties )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [in] */ BYTE *pbProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetProperty )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [in] */ void *pvBufferProperty,
|
||||
/* [in] */ DWORD dwBufferPropertySize);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetProperty )(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize);
|
||||
|
||||
END_INTERFACE
|
||||
} INSSBuffer3Vtbl;
|
||||
|
||||
interface INSSBuffer3
|
||||
{
|
||||
CONST_VTBL struct INSSBuffer3Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define INSSBuffer3_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define INSSBuffer3_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define INSSBuffer3_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define INSSBuffer3_GetLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer3_SetLength(This,dwLength) \
|
||||
(This)->lpVtbl -> SetLength(This,dwLength)
|
||||
|
||||
#define INSSBuffer3_GetMaxLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetMaxLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer3_GetBuffer(This,ppdwBuffer) \
|
||||
(This)->lpVtbl -> GetBuffer(This,ppdwBuffer)
|
||||
|
||||
#define INSSBuffer3_GetBufferAndLength(This,ppdwBuffer,pdwLength) \
|
||||
(This)->lpVtbl -> GetBufferAndLength(This,ppdwBuffer,pdwLength)
|
||||
|
||||
|
||||
#define INSSBuffer3_GetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> GetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
#define INSSBuffer3_SetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> SetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
|
||||
#define INSSBuffer3_SetProperty(This,guidBufferProperty,pvBufferProperty,dwBufferPropertySize) \
|
||||
(This)->lpVtbl -> SetProperty(This,guidBufferProperty,pvBufferProperty,dwBufferPropertySize)
|
||||
|
||||
#define INSSBuffer3_GetProperty(This,guidBufferProperty,pvBufferProperty,pdwBufferPropertySize) \
|
||||
(This)->lpVtbl -> GetProperty(This,guidBufferProperty,pvBufferProperty,pdwBufferPropertySize)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer3_SetProperty_Proxy(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [in] */ void *pvBufferProperty,
|
||||
/* [in] */ DWORD dwBufferPropertySize);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer3_SetProperty_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer3_GetProperty_Proxy(
|
||||
INSSBuffer3 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer3_GetProperty_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __INSSBuffer3_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __INSSBuffer4_INTERFACE_DEFINED__
|
||||
#define __INSSBuffer4_INTERFACE_DEFINED__
|
||||
|
||||
/* interface INSSBuffer4 */
|
||||
/* [version][uuid][unique][object][local] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_INSSBuffer4;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("B6B8FD5A-32E2-49d4-A910-C26CC85465ED")
|
||||
INSSBuffer4 : public INSSBuffer3
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE GetPropertyCount(
|
||||
/* [out] */ DWORD *pcBufferProperties) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetPropertyByIndex(
|
||||
/* [in] */ DWORD dwBufferPropertyIndex,
|
||||
/* [out] */ GUID *pguidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct INSSBuffer4Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
INSSBuffer4 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
INSSBuffer4 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetLength )(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetLength )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ DWORD dwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetMaxLength )(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBuffer )(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetBufferAndLength )(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ BYTE **ppdwBuffer,
|
||||
/* [out] */ DWORD *pdwLength);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetSampleProperties )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [out] */ BYTE *pbProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetSampleProperties )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ DWORD cbProperties,
|
||||
/* [in] */ BYTE *pbProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetProperty )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [in] */ void *pvBufferProperty,
|
||||
/* [in] */ DWORD dwBufferPropertySize);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetProperty )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ GUID guidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetPropertyCount )(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ DWORD *pcBufferProperties);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetPropertyByIndex )(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ DWORD dwBufferPropertyIndex,
|
||||
/* [out] */ GUID *pguidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize);
|
||||
|
||||
END_INTERFACE
|
||||
} INSSBuffer4Vtbl;
|
||||
|
||||
interface INSSBuffer4
|
||||
{
|
||||
CONST_VTBL struct INSSBuffer4Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define INSSBuffer4_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define INSSBuffer4_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define INSSBuffer4_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define INSSBuffer4_GetLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer4_SetLength(This,dwLength) \
|
||||
(This)->lpVtbl -> SetLength(This,dwLength)
|
||||
|
||||
#define INSSBuffer4_GetMaxLength(This,pdwLength) \
|
||||
(This)->lpVtbl -> GetMaxLength(This,pdwLength)
|
||||
|
||||
#define INSSBuffer4_GetBuffer(This,ppdwBuffer) \
|
||||
(This)->lpVtbl -> GetBuffer(This,ppdwBuffer)
|
||||
|
||||
#define INSSBuffer4_GetBufferAndLength(This,ppdwBuffer,pdwLength) \
|
||||
(This)->lpVtbl -> GetBufferAndLength(This,ppdwBuffer,pdwLength)
|
||||
|
||||
|
||||
#define INSSBuffer4_GetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> GetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
#define INSSBuffer4_SetSampleProperties(This,cbProperties,pbProperties) \
|
||||
(This)->lpVtbl -> SetSampleProperties(This,cbProperties,pbProperties)
|
||||
|
||||
|
||||
#define INSSBuffer4_SetProperty(This,guidBufferProperty,pvBufferProperty,dwBufferPropertySize) \
|
||||
(This)->lpVtbl -> SetProperty(This,guidBufferProperty,pvBufferProperty,dwBufferPropertySize)
|
||||
|
||||
#define INSSBuffer4_GetProperty(This,guidBufferProperty,pvBufferProperty,pdwBufferPropertySize) \
|
||||
(This)->lpVtbl -> GetProperty(This,guidBufferProperty,pvBufferProperty,pdwBufferPropertySize)
|
||||
|
||||
|
||||
#define INSSBuffer4_GetPropertyCount(This,pcBufferProperties) \
|
||||
(This)->lpVtbl -> GetPropertyCount(This,pcBufferProperties)
|
||||
|
||||
#define INSSBuffer4_GetPropertyByIndex(This,dwBufferPropertyIndex,pguidBufferProperty,pvBufferProperty,pdwBufferPropertySize) \
|
||||
(This)->lpVtbl -> GetPropertyByIndex(This,dwBufferPropertyIndex,pguidBufferProperty,pvBufferProperty,pdwBufferPropertySize)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer4_GetPropertyCount_Proxy(
|
||||
INSSBuffer4 * This,
|
||||
/* [out] */ DWORD *pcBufferProperties);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer4_GetPropertyCount_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE INSSBuffer4_GetPropertyByIndex_Proxy(
|
||||
INSSBuffer4 * This,
|
||||
/* [in] */ DWORD dwBufferPropertyIndex,
|
||||
/* [out] */ GUID *pguidBufferProperty,
|
||||
/* [out] */ void *pvBufferProperty,
|
||||
/* [out][in] */ DWORD *pdwBufferPropertySize);
|
||||
|
||||
|
||||
void __RPC_STUB INSSBuffer4_GetPropertyByIndex_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __INSSBuffer4_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IWMSBufferAllocator_INTERFACE_DEFINED__
|
||||
#define __IWMSBufferAllocator_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IWMSBufferAllocator */
|
||||
/* [version][uuid][unique][object][local] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IWMSBufferAllocator;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("61103CA4-2033-11d2-9EF1-006097D2D7CF")
|
||||
IWMSBufferAllocator : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE AllocatePageSizeBuffer(
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer) = 0;
|
||||
|
||||
};
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct IWMSBufferAllocatorVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
IWMSBufferAllocator * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
IWMSBufferAllocator * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
IWMSBufferAllocator * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )(
|
||||
IWMSBufferAllocator * This,
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *AllocatePageSizeBuffer )(
|
||||
IWMSBufferAllocator * This,
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer);
|
||||
|
||||
END_INTERFACE
|
||||
} IWMSBufferAllocatorVtbl;
|
||||
|
||||
interface IWMSBufferAllocator
|
||||
{
|
||||
CONST_VTBL struct IWMSBufferAllocatorVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define IWMSBufferAllocator_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IWMSBufferAllocator_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IWMSBufferAllocator_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IWMSBufferAllocator_AllocateBuffer(This,dwMaxBufferSize,ppBuffer) \
|
||||
(This)->lpVtbl -> AllocateBuffer(This,dwMaxBufferSize,ppBuffer)
|
||||
|
||||
#define IWMSBufferAllocator_AllocatePageSizeBuffer(This,dwMaxBufferSize,ppBuffer) \
|
||||
(This)->lpVtbl -> AllocatePageSizeBuffer(This,dwMaxBufferSize,ppBuffer)
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IWMSBufferAllocator_AllocateBuffer_Proxy(
|
||||
IWMSBufferAllocator * This,
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer);
|
||||
|
||||
|
||||
void __RPC_STUB IWMSBufferAllocator_AllocateBuffer_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IWMSBufferAllocator_AllocatePageSizeBuffer_Proxy(
|
||||
IWMSBufferAllocator * This,
|
||||
/* [in] */ DWORD dwMaxBufferSize,
|
||||
/* [out] */ INSSBuffer **ppBuffer);
|
||||
|
||||
|
||||
void __RPC_STUB IWMSBufferAllocator_AllocatePageSizeBuffer_Stub(
|
||||
IRpcStubBuffer *This,
|
||||
IRpcChannelBuffer *_pRpcChannelBuffer,
|
||||
PRPC_MESSAGE _pRpcMessage,
|
||||
DWORD *_pdwStubPhase);
|
||||
|
||||
|
||||
|
||||
#endif /* __IWMSBufferAllocator_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
12
fmod/win32/lib/wmsdk/include/wmsdk.h
Executable file
12
fmod/win32/lib/wmsdk/include/wmsdk.h
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
//*@@@+++@@@@******************************************************************
|
||||
//
|
||||
// Microsoft Windows Media
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//*@@@---@@@@******************************************************************
|
||||
//
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "wmsdkidl.h"
|
||||
#include "asferr.h"
|
||||
#include "nserror.h"
|
||||
19919
fmod/win32/lib/wmsdk/include/wmsdkidl.h
Executable file
19919
fmod/win32/lib/wmsdk/include/wmsdkidl.h
Executable file
File diff suppressed because it is too large
Load diff
774
fmod/win32/src/AFXRES.H
Executable file
774
fmod/win32/src/AFXRES.H
Executable file
|
|
@ -0,0 +1,774 @@
|
|||
// This is a part of the Microsoft Foundation Classes C++ library.
|
||||
// Copyright (C) 1992-1998 Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// This source code is only intended as a supplement to the
|
||||
// Microsoft Foundation Classes Reference and related
|
||||
// electronic documentation provided with the library.
|
||||
// See these sources for detailed information regarding the
|
||||
// Microsoft Foundation Classes product.
|
||||
|
||||
#ifndef __AFXRES_H__
|
||||
#define __AFXRES_H__
|
||||
|
||||
#ifdef RC_INVOKED
|
||||
#ifndef _INC_WINDOWS
|
||||
#define _INC_WINDOWS
|
||||
#include "winres.h" // extract from windows header
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _AFX_MINREBUILD
|
||||
#pragma component(minrebuild, off)
|
||||
#endif
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// MFC resource types (see Technical note TN024 for implementation details)
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
#define RT_DLGINIT MAKEINTRESOURCE(240)
|
||||
#define RT_TOOLBAR MAKEINTRESOURCE(241)
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// General style bits etc
|
||||
|
||||
// ControlBar styles
|
||||
#define CBRS_ALIGN_LEFT 0x1000L
|
||||
#define CBRS_ALIGN_TOP 0x2000L
|
||||
#define CBRS_ALIGN_RIGHT 0x4000L
|
||||
#define CBRS_ALIGN_BOTTOM 0x8000L
|
||||
#define CBRS_ALIGN_ANY 0xF000L
|
||||
|
||||
#define CBRS_BORDER_LEFT 0x0100L
|
||||
#define CBRS_BORDER_TOP 0x0200L
|
||||
#define CBRS_BORDER_RIGHT 0x0400L
|
||||
#define CBRS_BORDER_BOTTOM 0x0800L
|
||||
#define CBRS_BORDER_ANY 0x0F00L
|
||||
|
||||
#define CBRS_TOOLTIPS 0x0010L
|
||||
#define CBRS_FLYBY 0x0020L
|
||||
#define CBRS_FLOAT_MULTI 0x0040L
|
||||
#define CBRS_BORDER_3D 0x0080L
|
||||
#define CBRS_HIDE_INPLACE 0x0008L
|
||||
#define CBRS_SIZE_DYNAMIC 0x0004L
|
||||
#define CBRS_SIZE_FIXED 0x0002L
|
||||
#define CBRS_FLOATING 0x0001L
|
||||
|
||||
#define CBRS_GRIPPER 0x00400000L
|
||||
|
||||
#define CBRS_ORIENT_HORZ (CBRS_ALIGN_TOP|CBRS_ALIGN_BOTTOM)
|
||||
#define CBRS_ORIENT_VERT (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT)
|
||||
#define CBRS_ORIENT_ANY (CBRS_ORIENT_HORZ|CBRS_ORIENT_VERT)
|
||||
|
||||
#define CBRS_ALL 0x0040FFFFL
|
||||
|
||||
// the CBRS_ style is made up of an alignment style and a draw border style
|
||||
// the alignment styles are mutually exclusive
|
||||
// the draw border styles may be combined
|
||||
#define CBRS_NOALIGN 0x00000000L
|
||||
#define CBRS_LEFT (CBRS_ALIGN_LEFT|CBRS_BORDER_RIGHT)
|
||||
#define CBRS_TOP (CBRS_ALIGN_TOP|CBRS_BORDER_BOTTOM)
|
||||
#define CBRS_RIGHT (CBRS_ALIGN_RIGHT|CBRS_BORDER_LEFT)
|
||||
#define CBRS_BOTTOM (CBRS_ALIGN_BOTTOM|CBRS_BORDER_TOP)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard window components
|
||||
|
||||
// Mode indicators in status bar - these are routed like commands
|
||||
#define ID_INDICATOR_EXT 0xE700 // extended selection indicator
|
||||
#define ID_INDICATOR_CAPS 0xE701 // cap lock indicator
|
||||
#define ID_INDICATOR_NUM 0xE702 // num lock indicator
|
||||
#define ID_INDICATOR_SCRL 0xE703 // scroll lock indicator
|
||||
#define ID_INDICATOR_OVR 0xE704 // overtype mode indicator
|
||||
#define ID_INDICATOR_REC 0xE705 // record mode indicator
|
||||
#define ID_INDICATOR_KANA 0xE706 // kana lock indicator
|
||||
|
||||
#define ID_SEPARATOR 0 // special separator value
|
||||
|
||||
#ifndef RC_INVOKED // code only
|
||||
// Standard control bars (IDW = window ID)
|
||||
#define AFX_IDW_CONTROLBAR_FIRST 0xE800
|
||||
#define AFX_IDW_CONTROLBAR_LAST 0xE8FF
|
||||
|
||||
#define AFX_IDW_TOOLBAR 0xE800 // main Toolbar for window
|
||||
#define AFX_IDW_STATUS_BAR 0xE801 // Status bar window
|
||||
#define AFX_IDW_PREVIEW_BAR 0xE802 // PrintPreview Dialog Bar
|
||||
#define AFX_IDW_RESIZE_BAR 0xE803 // OLE in-place resize bar
|
||||
#define AFX_IDW_REBAR 0xE804 // COMCTL32 "rebar" Bar
|
||||
#define AFX_IDW_DIALOGBAR 0xE805 // CDialogBar
|
||||
|
||||
// Note: If your application supports docking toolbars, you should
|
||||
// not use the following IDs for your own toolbars. The IDs chosen
|
||||
// are at the top of the first 32 such that the bars will be hidden
|
||||
// while in print preview mode, and are not likely to conflict with
|
||||
// IDs your application may have used succesfully in the past.
|
||||
|
||||
#define AFX_IDW_DOCKBAR_TOP 0xE81B
|
||||
#define AFX_IDW_DOCKBAR_LEFT 0xE81C
|
||||
#define AFX_IDW_DOCKBAR_RIGHT 0xE81D
|
||||
#define AFX_IDW_DOCKBAR_BOTTOM 0xE81E
|
||||
#define AFX_IDW_DOCKBAR_FLOAT 0xE81F
|
||||
|
||||
// Macro for mapping standard control bars to bitmask (limit of 32)
|
||||
#define AFX_CONTROLBAR_MASK(nIDC) (1L << (nIDC - AFX_IDW_CONTROLBAR_FIRST))
|
||||
|
||||
// parts of Main Frame
|
||||
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
|
||||
#define AFX_IDW_PANE_LAST 0xE9ff
|
||||
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
|
||||
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
|
||||
|
||||
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
|
||||
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
|
||||
#endif //!RC_INVOKED
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
|
||||
// common style for form views
|
||||
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE | WS_BORDER)
|
||||
|
||||
#endif //!APSTUDIO_INVOKED
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard app configurable strings
|
||||
|
||||
// for application title (defaults to EXE name or name in constructor)
|
||||
#define AFX_IDS_APP_TITLE 0xE000
|
||||
// idle message bar line
|
||||
#define AFX_IDS_IDLEMESSAGE 0xE001
|
||||
// message bar line when in shift-F1 help mode
|
||||
#define AFX_IDS_HELPMODEMESSAGE 0xE002
|
||||
// document title when editing OLE embedding
|
||||
#define AFX_IDS_APP_TITLE_EMBEDDING 0xE003
|
||||
// company name
|
||||
#define AFX_IDS_COMPANY_NAME 0xE004
|
||||
// object name when server is inplace
|
||||
#define AFX_IDS_OBJ_TITLE_INPLACE 0xE005
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard Commands
|
||||
|
||||
// File commands
|
||||
#define ID_FILE_NEW 0xE100
|
||||
#define ID_FILE_OPEN 0xE101
|
||||
#define ID_FILE_CLOSE 0xE102
|
||||
#define ID_FILE_SAVE 0xE103
|
||||
#define ID_FILE_SAVE_AS 0xE104
|
||||
#define ID_FILE_PAGE_SETUP 0xE105
|
||||
#define ID_FILE_PRINT_SETUP 0xE106
|
||||
#define ID_FILE_PRINT 0xE107
|
||||
#define ID_FILE_PRINT_DIRECT 0xE108
|
||||
#define ID_FILE_PRINT_PREVIEW 0xE109
|
||||
#define ID_FILE_UPDATE 0xE10A
|
||||
#define ID_FILE_SAVE_COPY_AS 0xE10B
|
||||
#define ID_FILE_SEND_MAIL 0xE10C
|
||||
|
||||
#define ID_FILE_MRU_FIRST 0xE110
|
||||
#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
|
||||
#define ID_FILE_MRU_FILE2 0xE111
|
||||
#define ID_FILE_MRU_FILE3 0xE112
|
||||
#define ID_FILE_MRU_FILE4 0xE113
|
||||
#define ID_FILE_MRU_FILE5 0xE114
|
||||
#define ID_FILE_MRU_FILE6 0xE115
|
||||
#define ID_FILE_MRU_FILE7 0xE116
|
||||
#define ID_FILE_MRU_FILE8 0xE117
|
||||
#define ID_FILE_MRU_FILE9 0xE118
|
||||
#define ID_FILE_MRU_FILE10 0xE119
|
||||
#define ID_FILE_MRU_FILE11 0xE11A
|
||||
#define ID_FILE_MRU_FILE12 0xE11B
|
||||
#define ID_FILE_MRU_FILE13 0xE11C
|
||||
#define ID_FILE_MRU_FILE14 0xE11D
|
||||
#define ID_FILE_MRU_FILE15 0xE11E
|
||||
#define ID_FILE_MRU_FILE16 0xE11F
|
||||
#define ID_FILE_MRU_LAST 0xE11F
|
||||
|
||||
// Edit commands
|
||||
#define ID_EDIT_CLEAR 0xE120
|
||||
#define ID_EDIT_CLEAR_ALL 0xE121
|
||||
#define ID_EDIT_COPY 0xE122
|
||||
#define ID_EDIT_CUT 0xE123
|
||||
#define ID_EDIT_FIND 0xE124
|
||||
#define ID_EDIT_PASTE 0xE125
|
||||
#define ID_EDIT_PASTE_LINK 0xE126
|
||||
#define ID_EDIT_PASTE_SPECIAL 0xE127
|
||||
#define ID_EDIT_REPEAT 0xE128
|
||||
#define ID_EDIT_REPLACE 0xE129
|
||||
#define ID_EDIT_SELECT_ALL 0xE12A
|
||||
#define ID_EDIT_UNDO 0xE12B
|
||||
#define ID_EDIT_REDO 0xE12C
|
||||
|
||||
// Window commands
|
||||
#define ID_WINDOW_NEW 0xE130
|
||||
#define ID_WINDOW_ARRANGE 0xE131
|
||||
#define ID_WINDOW_CASCADE 0xE132
|
||||
#define ID_WINDOW_TILE_HORZ 0xE133
|
||||
#define ID_WINDOW_TILE_VERT 0xE134
|
||||
#define ID_WINDOW_SPLIT 0xE135
|
||||
#ifndef RC_INVOKED // code only
|
||||
#define AFX_IDM_WINDOW_FIRST 0xE130
|
||||
#define AFX_IDM_WINDOW_LAST 0xE13F
|
||||
#define AFX_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
|
||||
#endif //!RC_INVOKED
|
||||
|
||||
// Help and App commands
|
||||
#define ID_APP_ABOUT 0xE140
|
||||
#define ID_APP_EXIT 0xE141
|
||||
#define ID_HELP_INDEX 0xE142
|
||||
#define ID_HELP_FINDER 0xE143
|
||||
#define ID_HELP_USING 0xE144
|
||||
#define ID_CONTEXT_HELP 0xE145 // shift-F1
|
||||
// special commands for processing help
|
||||
#define ID_HELP 0xE146 // first attempt for F1
|
||||
#define ID_DEFAULT_HELP 0xE147 // last attempt
|
||||
|
||||
// Misc
|
||||
#define ID_NEXT_PANE 0xE150
|
||||
#define ID_PREV_PANE 0xE151
|
||||
|
||||
// Format
|
||||
#define ID_FORMAT_FONT 0xE160
|
||||
|
||||
// OLE commands
|
||||
#define ID_OLE_INSERT_NEW 0xE200
|
||||
#define ID_OLE_EDIT_LINKS 0xE201
|
||||
#define ID_OLE_EDIT_CONVERT 0xE202
|
||||
#define ID_OLE_EDIT_CHANGE_ICON 0xE203
|
||||
#define ID_OLE_EDIT_PROPERTIES 0xE204
|
||||
#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
|
||||
#ifndef RC_INVOKED // code only
|
||||
#define ID_OLE_VERB_LAST 0xE21F
|
||||
#endif //!RC_INVOKED
|
||||
|
||||
// for print preview dialog bar
|
||||
#define AFX_ID_PREVIEW_CLOSE 0xE300
|
||||
#define AFX_ID_PREVIEW_NUMPAGE 0xE301 // One/Two Page button
|
||||
#define AFX_ID_PREVIEW_NEXT 0xE302
|
||||
#define AFX_ID_PREVIEW_PREV 0xE303
|
||||
#define AFX_ID_PREVIEW_PRINT 0xE304
|
||||
#define AFX_ID_PREVIEW_ZOOMIN 0xE305
|
||||
#define AFX_ID_PREVIEW_ZOOMOUT 0xE306
|
||||
|
||||
// View commands (same number used as IDW used for control bar)
|
||||
#define ID_VIEW_TOOLBAR 0xE800
|
||||
#define ID_VIEW_STATUS_BAR 0xE801
|
||||
#define ID_VIEW_REBAR 0xE804
|
||||
#define ID_VIEW_AUTOARRANGE 0xE805
|
||||
// E810 -> E81F must be kept in order for RANGE macros
|
||||
#define ID_VIEW_SMALLICON 0xE810
|
||||
#define ID_VIEW_LARGEICON 0xE811
|
||||
#define ID_VIEW_LIST 0xE812
|
||||
#define ID_VIEW_DETAILS 0xE813
|
||||
#define ID_VIEW_LINEUP 0xE814
|
||||
#define ID_VIEW_BYNAME 0xE815
|
||||
#define AFX_ID_VIEW_MINIMUM ID_VIEW_SMALLICON
|
||||
#define AFX_ID_VIEW_MAXIMUM ID_VIEW_BYNAME
|
||||
// E800 -> E8FF reserved for other control bar commands
|
||||
|
||||
// RecordForm commands
|
||||
#define ID_RECORD_FIRST 0xE900
|
||||
#define ID_RECORD_LAST 0xE901
|
||||
#define ID_RECORD_NEXT 0xE902
|
||||
#define ID_RECORD_PREV 0xE903
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard control IDs
|
||||
|
||||
#ifdef IDC_STATIC
|
||||
#undef IDC_STATIC
|
||||
#endif
|
||||
#define IDC_STATIC (-1) // all static controls
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard string error/warnings
|
||||
|
||||
#ifndef RC_INVOKED // code only
|
||||
#define AFX_IDS_SCFIRST 0xEF00
|
||||
#endif //!RC_INVOKED
|
||||
|
||||
#define AFX_IDS_SCSIZE 0xEF00
|
||||
#define AFX_IDS_SCMOVE 0xEF01
|
||||
#define AFX_IDS_SCMINIMIZE 0xEF02
|
||||
#define AFX_IDS_SCMAXIMIZE 0xEF03
|
||||
#define AFX_IDS_SCNEXTWINDOW 0xEF04
|
||||
#define AFX_IDS_SCPREVWINDOW 0xEF05
|
||||
#define AFX_IDS_SCCLOSE 0xEF06
|
||||
#define AFX_IDS_SCRESTORE 0xEF12
|
||||
#define AFX_IDS_SCTASKLIST 0xEF13
|
||||
|
||||
#define AFX_IDS_MDICHILD 0xEF1F
|
||||
|
||||
#define AFX_IDS_DESKACCESSORY 0xEFDA
|
||||
|
||||
// General strings
|
||||
#define AFX_IDS_OPENFILE 0xF000
|
||||
#define AFX_IDS_SAVEFILE 0xF001
|
||||
#define AFX_IDS_ALLFILTER 0xF002
|
||||
#define AFX_IDS_UNTITLED 0xF003
|
||||
#define AFX_IDS_SAVEFILECOPY 0xF004
|
||||
#define AFX_IDS_PREVIEW_CLOSE 0xF005
|
||||
#define AFX_IDS_UNNAMED_FILE 0xF006
|
||||
#define AFX_IDS_HIDE 0xF011
|
||||
|
||||
// MFC Standard Exception Error messages
|
||||
#define AFX_IDP_NO_ERROR_AVAILABLE 0xF020
|
||||
#define AFX_IDS_NOT_SUPPORTED_EXCEPTION 0xF021
|
||||
#define AFX_IDS_RESOURCE_EXCEPTION 0xF022
|
||||
#define AFX_IDS_MEMORY_EXCEPTION 0xF023
|
||||
#define AFX_IDS_USER_EXCEPTION 0xF024
|
||||
|
||||
// Printing and print preview strings
|
||||
#define AFX_IDS_PRINTONPORT 0xF040
|
||||
#define AFX_IDS_ONEPAGE 0xF041
|
||||
#define AFX_IDS_TWOPAGE 0xF042
|
||||
#define AFX_IDS_PRINTPAGENUM 0xF043
|
||||
#define AFX_IDS_PREVIEWPAGEDESC 0xF044
|
||||
#define AFX_IDS_PRINTDEFAULTEXT 0xF045
|
||||
#define AFX_IDS_PRINTDEFAULT 0xF046
|
||||
#define AFX_IDS_PRINTFILTER 0xF047
|
||||
#define AFX_IDS_PRINTCAPTION 0xF048
|
||||
#define AFX_IDS_PRINTTOFILE 0xF049
|
||||
|
||||
|
||||
// OLE strings
|
||||
#define AFX_IDS_OBJECT_MENUITEM 0xF080
|
||||
#define AFX_IDS_EDIT_VERB 0xF081
|
||||
#define AFX_IDS_ACTIVATE_VERB 0xF082
|
||||
#define AFX_IDS_CHANGE_LINK 0xF083
|
||||
#define AFX_IDS_AUTO 0xF084
|
||||
#define AFX_IDS_MANUAL 0xF085
|
||||
#define AFX_IDS_FROZEN 0xF086
|
||||
#define AFX_IDS_ALL_FILES 0xF087
|
||||
// dynamically changing menu items
|
||||
#define AFX_IDS_SAVE_MENU 0xF088
|
||||
#define AFX_IDS_UPDATE_MENU 0xF089
|
||||
#define AFX_IDS_SAVE_AS_MENU 0xF08A
|
||||
#define AFX_IDS_SAVE_COPY_AS_MENU 0xF08B
|
||||
#define AFX_IDS_EXIT_MENU 0xF08C
|
||||
#define AFX_IDS_UPDATING_ITEMS 0xF08D
|
||||
// COlePasteSpecialDialog defines
|
||||
#define AFX_IDS_METAFILE_FORMAT 0xF08E
|
||||
#define AFX_IDS_DIB_FORMAT 0xF08F
|
||||
#define AFX_IDS_BITMAP_FORMAT 0xF090
|
||||
#define AFX_IDS_LINKSOURCE_FORMAT 0xF091
|
||||
#define AFX_IDS_EMBED_FORMAT 0xF092
|
||||
// other OLE utility strings
|
||||
#define AFX_IDS_PASTELINKEDTYPE 0xF094
|
||||
#define AFX_IDS_UNKNOWNTYPE 0xF095
|
||||
#define AFX_IDS_RTF_FORMAT 0xF096
|
||||
#define AFX_IDS_TEXT_FORMAT 0xF097
|
||||
// OLE datatype format error strings
|
||||
#define AFX_IDS_INVALID_CURRENCY 0xF098
|
||||
#define AFX_IDS_INVALID_DATETIME 0xF099
|
||||
#define AFX_IDS_INVALID_DATETIMESPAN 0xF09A
|
||||
|
||||
// General error / prompt strings
|
||||
#define AFX_IDP_INVALID_FILENAME 0xF100
|
||||
#define AFX_IDP_FAILED_TO_OPEN_DOC 0xF101
|
||||
#define AFX_IDP_FAILED_TO_SAVE_DOC 0xF102
|
||||
#define AFX_IDP_ASK_TO_SAVE 0xF103
|
||||
#define AFX_IDP_FAILED_TO_CREATE_DOC 0xF104
|
||||
#define AFX_IDP_FILE_TOO_LARGE 0xF105
|
||||
#define AFX_IDP_FAILED_TO_START_PRINT 0xF106
|
||||
#define AFX_IDP_FAILED_TO_LAUNCH_HELP 0xF107
|
||||
#define AFX_IDP_INTERNAL_FAILURE 0xF108 // general failure
|
||||
#define AFX_IDP_COMMAND_FAILURE 0xF109 // command failure
|
||||
#define AFX_IDP_FAILED_MEMORY_ALLOC 0xF10A
|
||||
#define AFX_IDP_UNREG_DONE 0xF10B
|
||||
#define AFX_IDP_UNREG_FAILURE 0xF10C
|
||||
#define AFX_IDP_DLL_LOAD_FAILED 0xF10D
|
||||
#define AFX_IDP_DLL_BAD_VERSION 0xF10E
|
||||
|
||||
// DDV parse errors
|
||||
#define AFX_IDP_PARSE_INT 0xF110
|
||||
#define AFX_IDP_PARSE_REAL 0xF111
|
||||
#define AFX_IDP_PARSE_INT_RANGE 0xF112
|
||||
#define AFX_IDP_PARSE_REAL_RANGE 0xF113
|
||||
#define AFX_IDP_PARSE_STRING_SIZE 0xF114
|
||||
#define AFX_IDP_PARSE_RADIO_BUTTON 0xF115
|
||||
#define AFX_IDP_PARSE_BYTE 0xF116
|
||||
#define AFX_IDP_PARSE_UINT 0xF117
|
||||
#define AFX_IDP_PARSE_DATETIME 0xF118
|
||||
#define AFX_IDP_PARSE_CURRENCY 0xF119
|
||||
|
||||
// CFile/CArchive error strings for user failure
|
||||
#define AFX_IDP_FAILED_INVALID_FORMAT 0xF120
|
||||
#define AFX_IDP_FAILED_INVALID_PATH 0xF121
|
||||
#define AFX_IDP_FAILED_DISK_FULL 0xF122
|
||||
#define AFX_IDP_FAILED_ACCESS_READ 0xF123
|
||||
#define AFX_IDP_FAILED_ACCESS_WRITE 0xF124
|
||||
#define AFX_IDP_FAILED_IO_ERROR_READ 0xF125
|
||||
#define AFX_IDP_FAILED_IO_ERROR_WRITE 0xF126
|
||||
|
||||
// OLE errors / prompt strings
|
||||
#define AFX_IDP_STATIC_OBJECT 0xF180
|
||||
#define AFX_IDP_FAILED_TO_CONNECT 0xF181
|
||||
#define AFX_IDP_SERVER_BUSY 0xF182
|
||||
#define AFX_IDP_BAD_VERB 0xF183
|
||||
#define AFX_IDS_NOT_DOCOBJECT 0xF184
|
||||
#define AFX_IDP_FAILED_TO_NOTIFY 0xF185
|
||||
#define AFX_IDP_FAILED_TO_LAUNCH 0xF186
|
||||
#define AFX_IDP_ASK_TO_UPDATE 0xF187
|
||||
#define AFX_IDP_FAILED_TO_UPDATE 0xF188
|
||||
#define AFX_IDP_FAILED_TO_REGISTER 0xF189
|
||||
#define AFX_IDP_FAILED_TO_AUTO_REGISTER 0xF18A
|
||||
#define AFX_IDP_FAILED_TO_CONVERT 0xF18B
|
||||
#define AFX_IDP_GET_NOT_SUPPORTED 0xF18C
|
||||
#define AFX_IDP_SET_NOT_SUPPORTED 0xF18D
|
||||
#define AFX_IDP_ASK_TO_DISCARD 0xF18E
|
||||
#define AFX_IDP_FAILED_TO_CREATE 0xF18F
|
||||
|
||||
// MAPI errors / prompt strings
|
||||
#define AFX_IDP_FAILED_MAPI_LOAD 0xF190
|
||||
#define AFX_IDP_INVALID_MAPI_DLL 0xF191
|
||||
#define AFX_IDP_FAILED_MAPI_SEND 0xF192
|
||||
|
||||
#define AFX_IDP_FILE_NONE 0xF1A0
|
||||
#define AFX_IDP_FILE_GENERIC 0xF1A1
|
||||
#define AFX_IDP_FILE_NOT_FOUND 0xF1A2
|
||||
#define AFX_IDP_FILE_BAD_PATH 0xF1A3
|
||||
#define AFX_IDP_FILE_TOO_MANY_OPEN 0xF1A4
|
||||
#define AFX_IDP_FILE_ACCESS_DENIED 0xF1A5
|
||||
#define AFX_IDP_FILE_INVALID_FILE 0xF1A6
|
||||
#define AFX_IDP_FILE_REMOVE_CURRENT 0xF1A7
|
||||
#define AFX_IDP_FILE_DIR_FULL 0xF1A8
|
||||
#define AFX_IDP_FILE_BAD_SEEK 0xF1A9
|
||||
#define AFX_IDP_FILE_HARD_IO 0xF1AA
|
||||
#define AFX_IDP_FILE_SHARING 0xF1AB
|
||||
#define AFX_IDP_FILE_LOCKING 0xF1AC
|
||||
#define AFX_IDP_FILE_DISKFULL 0xF1AD
|
||||
#define AFX_IDP_FILE_EOF 0xF1AE
|
||||
|
||||
#define AFX_IDP_ARCH_NONE 0xF1B0
|
||||
#define AFX_IDP_ARCH_GENERIC 0xF1B1
|
||||
#define AFX_IDP_ARCH_READONLY 0xF1B2
|
||||
#define AFX_IDP_ARCH_ENDOFFILE 0xF1B3
|
||||
#define AFX_IDP_ARCH_WRITEONLY 0xF1B4
|
||||
#define AFX_IDP_ARCH_BADINDEX 0xF1B5
|
||||
#define AFX_IDP_ARCH_BADCLASS 0xF1B6
|
||||
#define AFX_IDP_ARCH_BADSCHEMA 0xF1B7
|
||||
|
||||
#define AFX_IDS_OCC_SCALEUNITS_PIXELS 0xF1C0
|
||||
|
||||
// 0xf200-0xf20f reserved
|
||||
|
||||
// font names and point sizes
|
||||
#define AFX_IDS_STATUS_FONT 0xF230
|
||||
#define AFX_IDS_TOOLTIP_FONT 0xF231
|
||||
#define AFX_IDS_UNICODE_FONT 0xF232
|
||||
#define AFX_IDS_MINI_FONT 0xF233
|
||||
|
||||
// ODBC Database errors / prompt strings
|
||||
#ifndef RC_INVOKED // code only
|
||||
#define AFX_IDP_SQL_FIRST 0xF280
|
||||
#endif //!RC_INVOKED
|
||||
#define AFX_IDP_SQL_CONNECT_FAIL 0xF281
|
||||
#define AFX_IDP_SQL_RECORDSET_FORWARD_ONLY 0xF282
|
||||
#define AFX_IDP_SQL_EMPTY_COLUMN_LIST 0xF283
|
||||
#define AFX_IDP_SQL_FIELD_SCHEMA_MISMATCH 0xF284
|
||||
#define AFX_IDP_SQL_ILLEGAL_MODE 0xF285
|
||||
#define AFX_IDP_SQL_MULTIPLE_ROWS_AFFECTED 0xF286
|
||||
#define AFX_IDP_SQL_NO_CURRENT_RECORD 0xF287
|
||||
#define AFX_IDP_SQL_NO_ROWS_AFFECTED 0xF288
|
||||
#define AFX_IDP_SQL_RECORDSET_READONLY 0xF289
|
||||
#define AFX_IDP_SQL_SQL_NO_TOTAL 0xF28A
|
||||
#define AFX_IDP_SQL_ODBC_LOAD_FAILED 0xF28B
|
||||
#define AFX_IDP_SQL_DYNASET_NOT_SUPPORTED 0xF28C
|
||||
#define AFX_IDP_SQL_SNAPSHOT_NOT_SUPPORTED 0xF28D
|
||||
#define AFX_IDP_SQL_API_CONFORMANCE 0xF28E
|
||||
#define AFX_IDP_SQL_SQL_CONFORMANCE 0xF28F
|
||||
#define AFX_IDP_SQL_NO_DATA_FOUND 0xF290
|
||||
#define AFX_IDP_SQL_ROW_UPDATE_NOT_SUPPORTED 0xF291
|
||||
#define AFX_IDP_SQL_ODBC_V2_REQUIRED 0xF292
|
||||
#define AFX_IDP_SQL_NO_POSITIONED_UPDATES 0xF293
|
||||
#define AFX_IDP_SQL_LOCK_MODE_NOT_SUPPORTED 0xF294
|
||||
#define AFX_IDP_SQL_DATA_TRUNCATED 0xF295
|
||||
#define AFX_IDP_SQL_ROW_FETCH 0xF296
|
||||
#define AFX_IDP_SQL_INCORRECT_ODBC 0xF297
|
||||
#define AFX_IDP_SQL_UPDATE_DELETE_FAILED 0xF298
|
||||
#define AFX_IDP_SQL_DYNAMIC_CURSOR_NOT_SUPPORTED 0xF299
|
||||
#define AFX_IDP_SQL_FIELD_NOT_FOUND 0xF29A
|
||||
#define AFX_IDP_SQL_BOOKMARKS_NOT_SUPPORTED 0xF29B
|
||||
#define AFX_IDP_SQL_BOOKMARKS_NOT_ENABLED 0xF29C
|
||||
|
||||
// ODBC Database strings
|
||||
#define AFX_IDS_DELETED 0xF29D
|
||||
|
||||
// DAO Database errors / prompt strings
|
||||
#ifndef RC_INVOKED // code only
|
||||
#define AFX_IDP_DAO_FIRST 0xF2B0
|
||||
#endif //!RC_INVOKED
|
||||
#define AFX_IDP_DAO_ENGINE_INITIALIZATION 0xF2B0
|
||||
#define AFX_IDP_DAO_DFX_BIND 0xF2B1
|
||||
#define AFX_IDP_DAO_OBJECT_NOT_OPEN 0xF2B2
|
||||
|
||||
// ICDAORecordset::GetRows Errors
|
||||
// These are not placed in DAO Errors collection
|
||||
// and must be handled directly by MFC.
|
||||
#define AFX_IDP_DAO_ROWTOOSHORT 0xF2B3
|
||||
#define AFX_IDP_DAO_BADBINDINFO 0xF2B4
|
||||
#define AFX_IDP_DAO_COLUMNUNAVAILABLE 0xF2B5
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Strings for ISAPI support
|
||||
|
||||
#define AFX_IDS_HTTP_TITLE 0xF2D1
|
||||
#define AFX_IDS_HTTP_NO_TEXT 0xF2D2
|
||||
#define AFX_IDS_HTTP_BAD_REQUEST 0xF2D3
|
||||
#define AFX_IDS_HTTP_AUTH_REQUIRED 0xF2D4
|
||||
#define AFX_IDS_HTTP_FORBIDDEN 0xF2D5
|
||||
#define AFX_IDS_HTTP_NOT_FOUND 0xF2D6
|
||||
#define AFX_IDS_HTTP_SERVER_ERROR 0xF2D7
|
||||
#define AFX_IDS_HTTP_NOT_IMPLEMENTED 0xF2D8
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AFX implementation - control IDs (AFX_IDC)
|
||||
|
||||
// Parts of dialogs
|
||||
#define AFX_IDC_LISTBOX 100
|
||||
#define AFX_IDC_CHANGE 101
|
||||
|
||||
// for print dialog
|
||||
#define AFX_IDC_PRINT_DOCNAME 201
|
||||
#define AFX_IDC_PRINT_PRINTERNAME 202
|
||||
#define AFX_IDC_PRINT_PORTNAME 203
|
||||
#define AFX_IDC_PRINT_PAGENUM 204
|
||||
|
||||
// Property Sheet control id's (determined with Spy++)
|
||||
#define ID_APPLY_NOW 0x3021
|
||||
#define ID_WIZBACK 0x3023
|
||||
#define ID_WIZNEXT 0x3024
|
||||
#define ID_WIZFINISH 0x3025
|
||||
#define AFX_IDC_TAB_CONTROL 0x3020
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// IDRs for standard components
|
||||
|
||||
#ifndef RC_INVOKED // code only
|
||||
// These are really COMMDLG dialogs, so there usually isn't a resource
|
||||
// for them, but these IDs are used as help IDs.
|
||||
#define AFX_IDD_FILEOPEN 28676
|
||||
#define AFX_IDD_FILESAVE 28677
|
||||
#define AFX_IDD_FONT 28678
|
||||
#define AFX_IDD_COLOR 28679
|
||||
#define AFX_IDD_PRINT 28680
|
||||
#define AFX_IDD_PRINTSETUP 28681
|
||||
#define AFX_IDD_FIND 28682
|
||||
#define AFX_IDD_REPLACE 28683
|
||||
#endif //!RC_INVOKED
|
||||
|
||||
// Standard dialogs app should leave alone (0x7801->)
|
||||
#define AFX_IDD_NEWTYPEDLG 30721
|
||||
#define AFX_IDD_PRINTDLG 30722
|
||||
#define AFX_IDD_PREVIEW_TOOLBAR 30723
|
||||
|
||||
// Dialogs defined for OLE2UI library
|
||||
#define AFX_IDD_INSERTOBJECT 30724
|
||||
#define AFX_IDD_CHANGEICON 30725
|
||||
#define AFX_IDD_CONVERT 30726
|
||||
#define AFX_IDD_PASTESPECIAL 30727
|
||||
#define AFX_IDD_EDITLINKS 30728
|
||||
#define AFX_IDD_FILEBROWSE 30729
|
||||
#define AFX_IDD_BUSY 30730
|
||||
|
||||
#define AFX_IDD_OBJECTPROPERTIES 30732
|
||||
#define AFX_IDD_CHANGESOURCE 30733
|
||||
|
||||
// Standard cursors (0x7901->)
|
||||
// AFX_IDC = Cursor resources
|
||||
#define AFX_IDC_CONTEXTHELP 30977 // context sensitive help
|
||||
#define AFX_IDC_MAGNIFY 30978 // print preview zoom
|
||||
#define AFX_IDC_SMALLARROWS 30979 // splitter
|
||||
#define AFX_IDC_HSPLITBAR 30980 // splitter
|
||||
#define AFX_IDC_VSPLITBAR 30981 // splitter
|
||||
#define AFX_IDC_NODROPCRSR 30982 // No Drop Cursor
|
||||
#define AFX_IDC_TRACKNWSE 30983 // tracker
|
||||
#define AFX_IDC_TRACKNESW 30984 // tracker
|
||||
#define AFX_IDC_TRACKNS 30985 // tracker
|
||||
#define AFX_IDC_TRACKWE 30986 // tracker
|
||||
#define AFX_IDC_TRACK4WAY 30987 // tracker
|
||||
#define AFX_IDC_MOVE4WAY 30988 // resize bar (server only)
|
||||
|
||||
// Mini frame window bitmap ID
|
||||
#define AFX_IDB_MINIFRAME_MENU 30994
|
||||
|
||||
// CheckListBox checks bitmap ID
|
||||
#define AFX_IDB_CHECKLISTBOX_NT 30995
|
||||
#define AFX_IDB_CHECKLISTBOX_95 30996
|
||||
|
||||
// AFX standard accelerator resources
|
||||
#define AFX_IDR_PREVIEW_ACCEL 30997
|
||||
|
||||
// AFX standard ICON IDs (for MFC V1 apps) (0x7A01->)
|
||||
#define AFX_IDI_STD_MDIFRAME 31233
|
||||
#define AFX_IDI_STD_FRAME 31234
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AFX OLE control implementation - control IDs (AFX_IDC)
|
||||
|
||||
// Font property page
|
||||
#define AFX_IDC_FONTPROP 1000
|
||||
#define AFX_IDC_FONTNAMES 1001
|
||||
#define AFX_IDC_FONTSTYLES 1002
|
||||
#define AFX_IDC_FONTSIZES 1003
|
||||
#define AFX_IDC_STRIKEOUT 1004
|
||||
#define AFX_IDC_UNDERLINE 1005
|
||||
#define AFX_IDC_SAMPLEBOX 1006
|
||||
|
||||
// Color property page
|
||||
#define AFX_IDC_COLOR_BLACK 1100
|
||||
#define AFX_IDC_COLOR_WHITE 1101
|
||||
#define AFX_IDC_COLOR_RED 1102
|
||||
#define AFX_IDC_COLOR_GREEN 1103
|
||||
#define AFX_IDC_COLOR_BLUE 1104
|
||||
#define AFX_IDC_COLOR_YELLOW 1105
|
||||
#define AFX_IDC_COLOR_MAGENTA 1106
|
||||
#define AFX_IDC_COLOR_CYAN 1107
|
||||
#define AFX_IDC_COLOR_GRAY 1108
|
||||
#define AFX_IDC_COLOR_LIGHTGRAY 1109
|
||||
#define AFX_IDC_COLOR_DARKRED 1110
|
||||
#define AFX_IDC_COLOR_DARKGREEN 1111
|
||||
#define AFX_IDC_COLOR_DARKBLUE 1112
|
||||
#define AFX_IDC_COLOR_LIGHTBROWN 1113
|
||||
#define AFX_IDC_COLOR_DARKMAGENTA 1114
|
||||
#define AFX_IDC_COLOR_DARKCYAN 1115
|
||||
#define AFX_IDC_COLORPROP 1116
|
||||
#define AFX_IDC_SYSTEMCOLORS 1117
|
||||
|
||||
// Picture porperty page
|
||||
#define AFX_IDC_PROPNAME 1201
|
||||
#define AFX_IDC_PICTURE 1202
|
||||
#define AFX_IDC_BROWSE 1203
|
||||
#define AFX_IDC_CLEAR 1204
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// IDRs for OLE control standard components
|
||||
|
||||
// Standard propery page dialogs app should leave alone (0x7E01->)
|
||||
#define AFX_IDD_PROPPAGE_COLOR 32257
|
||||
#define AFX_IDD_PROPPAGE_FONT 32258
|
||||
#define AFX_IDD_PROPPAGE_PICTURE 32259
|
||||
|
||||
#define AFX_IDB_TRUETYPE 32384
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Standard OLE control strings
|
||||
|
||||
// OLE Control page strings
|
||||
#define AFX_IDS_PROPPAGE_UNKNOWN 0xFE01
|
||||
#define AFX_IDS_COLOR_DESKTOP 0xFE04
|
||||
#define AFX_IDS_COLOR_APPWORKSPACE 0xFE05
|
||||
#define AFX_IDS_COLOR_WNDBACKGND 0xFE06
|
||||
#define AFX_IDS_COLOR_WNDTEXT 0xFE07
|
||||
#define AFX_IDS_COLOR_MENUBAR 0xFE08
|
||||
#define AFX_IDS_COLOR_MENUTEXT 0xFE09
|
||||
#define AFX_IDS_COLOR_ACTIVEBAR 0xFE0A
|
||||
#define AFX_IDS_COLOR_INACTIVEBAR 0xFE0B
|
||||
#define AFX_IDS_COLOR_ACTIVETEXT 0xFE0C
|
||||
#define AFX_IDS_COLOR_INACTIVETEXT 0xFE0D
|
||||
#define AFX_IDS_COLOR_ACTIVEBORDER 0xFE0E
|
||||
#define AFX_IDS_COLOR_INACTIVEBORDER 0xFE0F
|
||||
#define AFX_IDS_COLOR_WNDFRAME 0xFE10
|
||||
#define AFX_IDS_COLOR_SCROLLBARS 0xFE11
|
||||
#define AFX_IDS_COLOR_BTNFACE 0xFE12
|
||||
#define AFX_IDS_COLOR_BTNSHADOW 0xFE13
|
||||
#define AFX_IDS_COLOR_BTNTEXT 0xFE14
|
||||
#define AFX_IDS_COLOR_BTNHIGHLIGHT 0xFE15
|
||||
#define AFX_IDS_COLOR_DISABLEDTEXT 0xFE16
|
||||
#define AFX_IDS_COLOR_HIGHLIGHT 0xFE17
|
||||
#define AFX_IDS_COLOR_HIGHLIGHTTEXT 0xFE18
|
||||
#define AFX_IDS_REGULAR 0xFE19
|
||||
#define AFX_IDS_BOLD 0xFE1A
|
||||
#define AFX_IDS_ITALIC 0xFE1B
|
||||
#define AFX_IDS_BOLDITALIC 0xFE1C
|
||||
#define AFX_IDS_SAMPLETEXT 0xFE1D
|
||||
#define AFX_IDS_DISPLAYSTRING_FONT 0xFE1E
|
||||
#define AFX_IDS_DISPLAYSTRING_COLOR 0xFE1F
|
||||
#define AFX_IDS_DISPLAYSTRING_PICTURE 0xFE20
|
||||
#define AFX_IDS_PICTUREFILTER 0xFE21
|
||||
#define AFX_IDS_PICTYPE_UNKNOWN 0xFE22
|
||||
#define AFX_IDS_PICTYPE_NONE 0xFE23
|
||||
#define AFX_IDS_PICTYPE_BITMAP 0xFE24
|
||||
#define AFX_IDS_PICTYPE_METAFILE 0xFE25
|
||||
#define AFX_IDS_PICTYPE_ICON 0xFE26
|
||||
#define AFX_IDS_COLOR_PPG 0xFE28
|
||||
#define AFX_IDS_COLOR_PPG_CAPTION 0xFE29
|
||||
#define AFX_IDS_FONT_PPG 0xFE2A
|
||||
#define AFX_IDS_FONT_PPG_CAPTION 0xFE2B
|
||||
#define AFX_IDS_PICTURE_PPG 0xFE2C
|
||||
#define AFX_IDS_PICTURE_PPG_CAPTION 0xFE2D
|
||||
#define AFX_IDS_PICTUREBROWSETITLE 0xFE30
|
||||
#define AFX_IDS_BORDERSTYLE_0 0xFE31
|
||||
#define AFX_IDS_BORDERSTYLE_1 0xFE32
|
||||
|
||||
// OLE Control verb names
|
||||
#define AFX_IDS_VERB_EDIT 0xFE40
|
||||
#define AFX_IDS_VERB_PROPERTIES 0xFE41
|
||||
|
||||
// OLE Control internal error messages
|
||||
#define AFX_IDP_PICTURECANTOPEN 0xFE83
|
||||
#define AFX_IDP_PICTURECANTLOAD 0xFE84
|
||||
#define AFX_IDP_PICTURETOOLARGE 0xFE85
|
||||
#define AFX_IDP_PICTUREREADFAILED 0xFE86
|
||||
|
||||
// Standard OLE Control error strings
|
||||
#define AFX_IDP_E_ILLEGALFUNCTIONCALL 0xFEA0
|
||||
#define AFX_IDP_E_OVERFLOW 0xFEA1
|
||||
#define AFX_IDP_E_OUTOFMEMORY 0xFEA2
|
||||
#define AFX_IDP_E_DIVISIONBYZERO 0xFEA3
|
||||
#define AFX_IDP_E_OUTOFSTRINGSPACE 0xFEA4
|
||||
#define AFX_IDP_E_OUTOFSTACKSPACE 0xFEA5
|
||||
#define AFX_IDP_E_BADFILENAMEORNUMBER 0xFEA6
|
||||
#define AFX_IDP_E_FILENOTFOUND 0xFEA7
|
||||
#define AFX_IDP_E_BADFILEMODE 0xFEA8
|
||||
#define AFX_IDP_E_FILEALREADYOPEN 0xFEA9
|
||||
#define AFX_IDP_E_DEVICEIOERROR 0xFEAA
|
||||
#define AFX_IDP_E_FILEALREADYEXISTS 0xFEAB
|
||||
#define AFX_IDP_E_BADRECORDLENGTH 0xFEAC
|
||||
#define AFX_IDP_E_DISKFULL 0xFEAD
|
||||
#define AFX_IDP_E_BADRECORDNUMBER 0xFEAE
|
||||
#define AFX_IDP_E_BADFILENAME 0xFEAF
|
||||
#define AFX_IDP_E_TOOMANYFILES 0xFEB0
|
||||
#define AFX_IDP_E_DEVICEUNAVAILABLE 0xFEB1
|
||||
#define AFX_IDP_E_PERMISSIONDENIED 0xFEB2
|
||||
#define AFX_IDP_E_DISKNOTREADY 0xFEB3
|
||||
#define AFX_IDP_E_PATHFILEACCESSERROR 0xFEB4
|
||||
#define AFX_IDP_E_PATHNOTFOUND 0xFEB5
|
||||
#define AFX_IDP_E_INVALIDPATTERNSTRING 0xFEB6
|
||||
#define AFX_IDP_E_INVALIDUSEOFNULL 0xFEB7
|
||||
#define AFX_IDP_E_INVALIDFILEFORMAT 0xFEB8
|
||||
#define AFX_IDP_E_INVALIDPROPERTYVALUE 0xFEB9
|
||||
#define AFX_IDP_E_INVALIDPROPERTYARRAYINDEX 0xFEBA
|
||||
#define AFX_IDP_E_SETNOTSUPPORTEDATRUNTIME 0xFEBB
|
||||
#define AFX_IDP_E_SETNOTSUPPORTED 0xFEBC
|
||||
#define AFX_IDP_E_NEEDPROPERTYARRAYINDEX 0xFEBD
|
||||
#define AFX_IDP_E_SETNOTPERMITTED 0xFEBE
|
||||
#define AFX_IDP_E_GETNOTSUPPORTEDATRUNTIME 0xFEBF
|
||||
#define AFX_IDP_E_GETNOTSUPPORTED 0xFEC0
|
||||
#define AFX_IDP_E_PROPERTYNOTFOUND 0xFEC1
|
||||
#define AFX_IDP_E_INVALIDCLIPBOARDFORMAT 0xFEC2
|
||||
#define AFX_IDP_E_INVALIDPICTURE 0xFEC3
|
||||
#define AFX_IDP_E_PRINTERERROR 0xFEC4
|
||||
#define AFX_IDP_E_CANTSAVEFILETOTEMP 0xFEC5
|
||||
#define AFX_IDP_E_SEARCHTEXTNOTFOUND 0xFEC6
|
||||
#define AFX_IDP_E_REPLACEMENTSTOOLONG 0xFEC7
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _AFX_MINREBUILD
|
||||
#pragma component(minrebuild, on)
|
||||
#endif
|
||||
|
||||
#endif //__AFXRES_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
329
fmod/win32/src/MeteredSection.cpp
Executable file
329
fmod/win32/src/MeteredSection.cpp
Executable file
|
|
@ -0,0 +1,329 @@
|
|||
/************************************************************
|
||||
Module Name: MeteredSection.c
|
||||
Author: Dan Chou
|
||||
Description: Implements the metered section synchronization object
|
||||
************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include "MeteredSection.h"
|
||||
#include "../../src/fmod_memory.h"
|
||||
|
||||
// Internal function declarations
|
||||
BOOL InitMeteredSection(LPMETERED_SECTION lpMetSect, LONG lInitialCount,
|
||||
LONG lMaximumCount, LPCTSTR lpName, BOOL bOpenOnly);
|
||||
BOOL CreateMetSectEvent(LPMETERED_SECTION lpMetSect, LPCTSTR lpName, BOOL
|
||||
bOpenOnly);
|
||||
BOOL CreateMetSectFileView(LPMETERED_SECTION lpMetSect, LONG lInitialCount,
|
||||
LONG lMaximumCount, LPCTSTR lpName, BOOL bOpenOnly);
|
||||
void GetMeteredSectionLock(LPMETERED_SECTION lpMetSect);
|
||||
void ReleaseMeteredSectionLock(LPMETERED_SECTION lpMetSect);
|
||||
|
||||
/*
|
||||
* CreateMeteredSection
|
||||
*/
|
||||
LPMETERED_SECTION CreateMeteredSection(LONG lInitialCount,
|
||||
LONG lMaximumCount, LPCTSTR lpName)
|
||||
{
|
||||
LPMETERED_SECTION lpMetSect;
|
||||
|
||||
// Verify the parameters
|
||||
if ((lMaximumCount < 1) ||
|
||||
(lInitialCount > lMaximumCount) ||
|
||||
(lInitialCount < 0) ||
|
||||
((lpName) && (_tcslen(lpName) > MAX_METSECT_NAMELEN)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate memory for the metered section
|
||||
lpMetSect = (LPMETERED_SECTION)FMOD_Memory_Alloc(sizeof(METERED_SECTION));
|
||||
|
||||
// If the memory for the metered section was allocated okay,
|
||||
// initialize it
|
||||
if (lpMetSect)
|
||||
{
|
||||
if (!InitMeteredSection(lpMetSect, lInitialCount,
|
||||
lMaximumCount, lpName, FALSE))
|
||||
{
|
||||
CloseMeteredSection(lpMetSect);
|
||||
lpMetSect = NULL;
|
||||
}
|
||||
}
|
||||
return lpMetSect;
|
||||
}
|
||||
|
||||
/*
|
||||
* OpenMeteredSection
|
||||
*/
|
||||
#ifndef _WIN32_WCE
|
||||
LPMETERED_SECTION OpenMeteredSection(LPCTSTR lpName)
|
||||
{
|
||||
LPMETERED_SECTION lpMetSect = NULL;
|
||||
|
||||
if (lpName)
|
||||
{
|
||||
lpMetSect = (LPMETERED_SECTION)FMOD_Memory_Alloc(sizeof(METERED_SECTION));
|
||||
|
||||
// If the memory for the metered section was allocated okay
|
||||
if (lpMetSect)
|
||||
{
|
||||
if (!InitMeteredSection(lpMetSect, 0, 0, lpName, TRUE))
|
||||
{
|
||||
// Metered section failed to initialize
|
||||
CloseMeteredSection(lpMetSect);
|
||||
lpMetSect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lpMetSect;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* EnterMeteredSection
|
||||
*/
|
||||
DWORD EnterMeteredSection(LPMETERED_SECTION lpMetSect,
|
||||
DWORD dwMilliseconds)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
GetMeteredSectionLock(lpMetSect);
|
||||
|
||||
// We have access to the metered section, everything we
|
||||
// do now will be atomic
|
||||
if (lpMetSect->lpSharedInfo->lAvailableCount >= 1)
|
||||
{
|
||||
lpMetSect->lpSharedInfo->lAvailableCount--;
|
||||
ReleaseMeteredSectionLock(lpMetSect);
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
// Couldn't get in. Wait on the event object
|
||||
lpMetSect->lpSharedInfo->lThreadsWaiting++;
|
||||
ResetEvent(lpMetSect->hEvent);
|
||||
ReleaseMeteredSectionLock(lpMetSect);
|
||||
if (WaitForSingleObject(lpMetSect->hEvent,
|
||||
dwMilliseconds) == WAIT_TIMEOUT)
|
||||
{
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* LeaveMeteredSection
|
||||
*/
|
||||
BOOL LeaveMeteredSection(LPMETERED_SECTION lpMetSect, LONG lReleaseCount,
|
||||
LPLONG lpPreviousCount)
|
||||
{
|
||||
int iCount;
|
||||
GetMeteredSectionLock(lpMetSect);
|
||||
|
||||
// Save the old value if they want it
|
||||
if (lpPreviousCount)
|
||||
{
|
||||
*lpPreviousCount = lpMetSect->lpSharedInfo->lAvailableCount;
|
||||
}
|
||||
|
||||
// We have access to the metered section,
|
||||
// everything we do now will be atomic
|
||||
if ((lReleaseCount < 0) ||
|
||||
(lpMetSect->lpSharedInfo->lAvailableCount+lReleaseCount >
|
||||
lpMetSect->lpSharedInfo->lMaximumCount))
|
||||
{
|
||||
ReleaseMeteredSectionLock(lpMetSect);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
lpMetSect->lpSharedInfo->lAvailableCount += lReleaseCount;
|
||||
|
||||
// Set the event the appropriate number of times
|
||||
lReleaseCount =
|
||||
min(lReleaseCount,lpMetSect->lpSharedInfo->lThreadsWaiting);
|
||||
if (lpMetSect->lpSharedInfo->lThreadsWaiting)
|
||||
{
|
||||
for (iCount=0; iCount < lReleaseCount ; iCount++)
|
||||
{
|
||||
lpMetSect->lpSharedInfo->lThreadsWaiting--;
|
||||
SetEvent(lpMetSect->hEvent);
|
||||
}
|
||||
}
|
||||
ReleaseMeteredSectionLock(lpMetSect);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* CloseMeteredSection
|
||||
*/
|
||||
void CloseMeteredSection(LPMETERED_SECTION lpMetSect)
|
||||
{
|
||||
if (lpMetSect)
|
||||
{
|
||||
// Clean up
|
||||
#ifdef FILEMAPPING
|
||||
if (lpMetSect->lpSharedInfo) UnmapViewOfFile(lpMetSect->lpSharedInfo);
|
||||
if (lpMetSect->hFileMap) CloseHandle(lpMetSect->hFileMap);
|
||||
#else
|
||||
DeleteCriticalSection(&lpMetSect->hCrit);
|
||||
#endif
|
||||
|
||||
if (lpMetSect->hEvent) CloseHandle(lpMetSect->hEvent);
|
||||
FMOD_Memory_Free(lpMetSect);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* InitMeteredSection
|
||||
*/
|
||||
BOOL InitMeteredSection(LPMETERED_SECTION lpMetSect,
|
||||
LONG lInitialCount, LONG lMaximumCount,
|
||||
LPCTSTR lpName, BOOL bOpenOnly)
|
||||
{
|
||||
// Try to create the event object
|
||||
if (CreateMetSectEvent(lpMetSect, lpName, bOpenOnly))
|
||||
{
|
||||
#ifdef FILEMAPPING
|
||||
// Try to create the memory mapped file
|
||||
if (CreateMetSectFileView(lpMetSect, lInitialCount, lMaximumCount, lpName, bOpenOnly))
|
||||
#else
|
||||
lpMetSect->lpSharedInfo = &lpMetSect->SharedInfo;
|
||||
lpMetSect->lpSharedInfo->lThreadsWaiting = 0;
|
||||
lpMetSect->lpSharedInfo->lAvailableCount = lInitialCount;
|
||||
lpMetSect->lpSharedInfo->lMaximumCount = lMaximumCount;
|
||||
InitializeCriticalSection(&lpMetSect->hCrit);
|
||||
InterlockedExchange((long *)&(lpMetSect->lpSharedInfo->fInitialized), TRUE);
|
||||
#endif
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Error occured, return FALSE so the caller knows to clean up
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateMetSectEvent
|
||||
*/
|
||||
BOOL CreateMetSectEvent(LPMETERED_SECTION lpMetSect,
|
||||
LPCTSTR lpName, BOOL bOpenOnly)
|
||||
{
|
||||
TCHAR sz[MAX_PATH];
|
||||
if (lpName)
|
||||
{
|
||||
//wsprintf(sz, _TEXT("DKC_MSECT_EVT_%s"), lpName);
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
if (bOpenOnly)
|
||||
{
|
||||
lpMetSect->hEvent = OpenEvent(0, FALSE, sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// Create an auto-reset named event object
|
||||
lpMetSect->hEvent = CreateEvent(NULL, FALSE, FALSE, sz);
|
||||
#ifndef _WIN32_WCE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an auto-reset unnamed event object
|
||||
lpMetSect->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
}
|
||||
return (lpMetSect->hEvent ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
#ifdef FILEMAPPING
|
||||
/*
|
||||
* CreateMetSectFileView
|
||||
*/
|
||||
BOOL CreateMetSectFileView(LPMETERED_SECTION lpMetSect,
|
||||
LONG lInitialCount, LONG lMaximumCount,
|
||||
LPCTSTR lpName, BOOL bOpenOnly)
|
||||
{
|
||||
TCHAR sz[MAX_PATH];
|
||||
DWORD dwLastError;
|
||||
|
||||
if (lpName)
|
||||
{
|
||||
//wsprintf(sz, _TEXT("DKC_MSECT_MMF_%s"), lpName);
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
if (bOpenOnly)
|
||||
{
|
||||
lpMetSect->hFileMap = OpenFileMapping(0, FALSE, sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// Create a named file mapping
|
||||
lpMetSect->hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,
|
||||
NULL, PAGE_READWRITE, 0, sizeof(METSECT_SHARED_INFO), sz);
|
||||
#ifndef _WIN32_WCE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an unnamed file mapping
|
||||
lpMetSect->hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,
|
||||
NULL, PAGE_READWRITE, 0, sizeof(METSECT_SHARED_INFO), NULL);
|
||||
}
|
||||
|
||||
// Map a view of the file
|
||||
if (lpMetSect->hFileMap)
|
||||
{
|
||||
dwLastError = GetLastError();
|
||||
lpMetSect->lpSharedInfo = (LPMETSECT_SHARED_INFO)
|
||||
MapViewOfFile(lpMetSect->hFileMap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (lpMetSect->lpSharedInfo)
|
||||
{
|
||||
if (dwLastError != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
lpMetSect->lpSharedInfo->lSpinLock = 0;
|
||||
lpMetSect->lpSharedInfo->lThreadsWaiting = 0;
|
||||
lpMetSect->lpSharedInfo->lAvailableCount = lInitialCount;
|
||||
lpMetSect->lpSharedInfo->lMaximumCount = lMaximumCount;
|
||||
InterlockedExchange((long *)&(lpMetSect->lpSharedInfo->fInitialized), TRUE);
|
||||
}
|
||||
else
|
||||
{ // Already exists; wait for it to be initialized by the creator
|
||||
while (!lpMetSect->lpSharedInfo->fInitialized) Sleep(0);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GetMeteredSectionLock
|
||||
*/
|
||||
void GetMeteredSectionLock(LPMETERED_SECTION lpMetSect)
|
||||
{
|
||||
#if FILEMAPPING
|
||||
// Spin and get access to the metered section lock
|
||||
while (InterlockedExchange(&(lpMetSect->lpSharedInfo->lSpinLock), 1) != 0)
|
||||
Sleep(1);
|
||||
#else
|
||||
EnterCriticalSection(&lpMetSect->hCrit);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* ReleaseMeteredSectionLock
|
||||
*/
|
||||
void ReleaseMeteredSectionLock(LPMETERED_SECTION lpMetSect)
|
||||
{
|
||||
#if FILEMAPPING
|
||||
InterlockedExchange(&(lpMetSect->lpSharedInfo->lSpinLock), 0);
|
||||
#else
|
||||
LeaveCriticalSection(&lpMetSect->hCrit);
|
||||
#endif
|
||||
}
|
||||
62
fmod/win32/src/MeteredSection.h
Executable file
62
fmod/win32/src/MeteredSection.h
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
/************************************************************
|
||||
Module Name: MeteredSection.h
|
||||
Author: Dan Chou
|
||||
Description: Defines the metered section synchronization object
|
||||
************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef _METERED_SECTION_H_
|
||||
#define _METERED_SECTION_H_
|
||||
|
||||
#define MAX_METSECT_NAMELEN 128
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
//#define FILEMAPPING
|
||||
|
||||
// Shared info needed for metered section
|
||||
typedef struct _METSECT_SHARED_INFO {
|
||||
BOOL fInitialized; // Is the metered section initialized?
|
||||
#ifdef FILEMAPPING
|
||||
LONG lSpinLock; // Used to gain access to this structure
|
||||
#endif
|
||||
LONG lThreadsWaiting; // Count of threads waiting
|
||||
LONG lAvailableCount; // Available resource count
|
||||
LONG lMaximumCount; // Maximum resource count
|
||||
} METSECT_SHARED_INFO, *LPMETSECT_SHARED_INFO;
|
||||
|
||||
// The opaque Metered Section data structure
|
||||
typedef struct _METERED_SECTION {
|
||||
HANDLE hEvent; // Handle to a kernel event object
|
||||
#ifdef FILEMAPPING
|
||||
HANDLE hFileMap; // Handle to memory mapped file
|
||||
#else
|
||||
METSECT_SHARED_INFO SharedInfo;
|
||||
CRITICAL_SECTION hCrit;
|
||||
#endif
|
||||
LPMETSECT_SHARED_INFO lpSharedInfo;
|
||||
} METERED_SECTION, *LPMETERED_SECTION;
|
||||
|
||||
// Interface functions
|
||||
LPMETERED_SECTION
|
||||
CreateMeteredSection(LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
LPMETERED_SECTION OpenMeteredSection(LPCTSTR lpName);
|
||||
#endif
|
||||
|
||||
DWORD EnterMeteredSection(LPMETERED_SECTION lpMetSect,
|
||||
DWORD dwMilliseconds);
|
||||
BOOL LeaveMeteredSection(LPMETERED_SECTION lpMetSect,
|
||||
LONG lReleaseCount, LPLONG lpPreviousCount);
|
||||
void CloseMeteredSection(LPMETERED_SECTION lpMetSect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _METERED_SECTION_H_
|
||||
259
fmod/win32/src/asio/asio.cpp
Executable file
259
fmod/win32/src/asio/asio.cpp
Executable file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
Steinberg Audio Stream I/O API
|
||||
(c) 1996, Steinberg Soft- und Hardware GmbH
|
||||
|
||||
asio.cpp
|
||||
|
||||
asio functions entries which translate the
|
||||
asio interface to the asiodrvr class methods
|
||||
*/
|
||||
|
||||
#include "asiosys.h" // platform definition
|
||||
#include "asio.h"
|
||||
|
||||
#if MAC
|
||||
#include "asiodrvr.h"
|
||||
|
||||
#pragma export on
|
||||
|
||||
AsioDriver *theAsioDriver = 0;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
long main()
|
||||
{
|
||||
return 'ASIO';
|
||||
}
|
||||
|
||||
#elif WINDOWS
|
||||
|
||||
#include "windows.h"
|
||||
#include "iasiodrv.h"
|
||||
#include "asiodrivers.h"
|
||||
|
||||
IASIO *theAsioDriver = 0;
|
||||
extern AsioDrivers *asioDrivers;
|
||||
|
||||
#elif SGI || SUN || BEOS || LINUX
|
||||
#include "asiodrvr.h"
|
||||
static AsioDriver *theAsioDriver = 0;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
ASIOError ASIOInit(ASIODriverInfo *info)
|
||||
{
|
||||
#if MAC || SGI || SUN || BEOS || LINUX
|
||||
if(theAsioDriver)
|
||||
{
|
||||
delete theAsioDriver;
|
||||
theAsioDriver = 0;
|
||||
}
|
||||
info->driverVersion = 0;
|
||||
strcpy(info->name, "No ASIO Driver");
|
||||
theAsioDriver = getDriver();
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
strcpy(info->errorMessage, "Not enough memory for the ASIO driver!");
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
if(!theAsioDriver->init(info->sysRef))
|
||||
{
|
||||
theAsioDriver->getErrorMessage(info->errorMessage);
|
||||
delete theAsioDriver;
|
||||
theAsioDriver = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
strcpy(info->errorMessage, "No ASIO Driver Error");
|
||||
theAsioDriver->getDriverName(info->name);
|
||||
info->driverVersion = theAsioDriver->getDriverVersion();
|
||||
return ASE_OK;
|
||||
|
||||
#else
|
||||
|
||||
info->driverVersion = 0;
|
||||
strcpy(info->name, "No ASIO Driver");
|
||||
if(theAsioDriver) // must be loaded!
|
||||
{
|
||||
if(!theAsioDriver->init(info->sysRef))
|
||||
{
|
||||
theAsioDriver->getErrorMessage(info->errorMessage);
|
||||
theAsioDriver = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
|
||||
strcpy(info->errorMessage, "No ASIO Driver Error");
|
||||
theAsioDriver->getDriverName(info->name);
|
||||
info->driverVersion = theAsioDriver->getDriverVersion();
|
||||
return ASE_OK;
|
||||
}
|
||||
return ASE_NotPresent;
|
||||
|
||||
#endif // !MAC
|
||||
}
|
||||
|
||||
ASIOError ASIOExit(void)
|
||||
{
|
||||
if(theAsioDriver)
|
||||
{
|
||||
#if WINDOWS
|
||||
if (asioDrivers)
|
||||
{
|
||||
asioDrivers->removeCurrentDriver();
|
||||
}
|
||||
#else
|
||||
delete theAsioDriver;
|
||||
#endif
|
||||
}
|
||||
theAsioDriver = 0;
|
||||
return ASE_OK;
|
||||
}
|
||||
|
||||
ASIOError ASIOStart(void)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->start();
|
||||
}
|
||||
|
||||
ASIOError ASIOStop(void)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->stop();
|
||||
}
|
||||
|
||||
ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
*numInputChannels = *numOutputChannels = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->getChannels(numInputChannels, numOutputChannels);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
*inputLatency = *outputLatency = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->getLatencies(inputLatency, outputLatency);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
*minSize = *maxSize = *preferredSize = *granularity = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity);
|
||||
}
|
||||
|
||||
ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->canSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->getSampleRate(currentRate);
|
||||
}
|
||||
|
||||
ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->setSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
*numSources = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->getClockSources(clocks, numSources);
|
||||
}
|
||||
|
||||
ASIOError ASIOSetClockSource(long reference)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->setClockSource(reference);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->getSamplePosition(sPos, tStamp);
|
||||
}
|
||||
|
||||
ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
info->channelGroup = -1;
|
||||
info->type = ASIOSTInt16MSB;
|
||||
strcpy(info->name, "None");
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->getChannelInfo(info);
|
||||
}
|
||||
|
||||
ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
|
||||
long bufferSize, ASIOCallbacks *callbacks)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
{
|
||||
ASIOBufferInfo *info = bufferInfos;
|
||||
for(long i = 0; i < numChannels; i++, info++)
|
||||
info->buffers[0] = info->buffers[1] = 0;
|
||||
return ASE_NotPresent;
|
||||
}
|
||||
return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks);
|
||||
}
|
||||
|
||||
ASIOError ASIODisposeBuffers(void)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->disposeBuffers();
|
||||
}
|
||||
|
||||
ASIOError ASIOControlPanel(void)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->controlPanel();
|
||||
}
|
||||
|
||||
ASIOError ASIOFuture(long selector, void *opt)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->future(selector, opt);
|
||||
}
|
||||
|
||||
ASIOError ASIOOutputReady(void)
|
||||
{
|
||||
if(!theAsioDriver)
|
||||
return ASE_NotPresent;
|
||||
return theAsioDriver->outputReady();
|
||||
}
|
||||
|
||||
#if MAC
|
||||
} // extern "C"
|
||||
#pragma export off
|
||||
#endif
|
||||
|
||||
|
||||
963
fmod/win32/src/asio/asio.h
Executable file
963
fmod/win32/src/asio/asio.h
Executable file
|
|
@ -0,0 +1,963 @@
|
|||
//---------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Steinberg Audio Stream I/O API
|
||||
(c) 1997 - 1999, Steinberg Soft- und Hardware GmbH
|
||||
|
||||
ASIO Interface Specification v 2.0
|
||||
|
||||
basic concept is an i/o synchronous double-buffer scheme:
|
||||
|
||||
on bufferSwitch(index == 0), host will read/write:
|
||||
|
||||
after ASIOStart(), the
|
||||
read first input buffer A (index 0)
|
||||
| will be invalid (empty)
|
||||
* ------------------------
|
||||
|------------------------|-----------------------|
|
||||
| | |
|
||||
| Input Buffer A (0) | Input Buffer B (1) |
|
||||
| | |
|
||||
|------------------------|-----------------------|
|
||||
| | |
|
||||
| Output Buffer A (0) | Output Buffer B (1) |
|
||||
| | |
|
||||
|------------------------|-----------------------|
|
||||
* -------------------------
|
||||
| before calling ASIOStart(),
|
||||
write host will have filled output
|
||||
buffer B (index 1) already
|
||||
|
||||
*please* take special care of proper statement of input
|
||||
and output latencies (see ASIOGetLatencies()), these
|
||||
control sequencer sync accuracy
|
||||
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
|
||||
prototypes summary:
|
||||
|
||||
ASIOError ASIOInit(ASIODriverInfo *info);
|
||||
ASIOError ASIOExit(void);
|
||||
ASIOError ASIOStart(void);
|
||||
ASIOError ASIOStop(void);
|
||||
ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);
|
||||
ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);
|
||||
ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
|
||||
ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);
|
||||
ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);
|
||||
ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);
|
||||
ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);
|
||||
ASIOError ASIOSetClockSource(long reference);
|
||||
ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
|
||||
ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
|
||||
ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
|
||||
long bufferSize, ASIOCallbacks *callbacks);
|
||||
ASIOError ASIODisposeBuffers(void);
|
||||
ASIOError ASIOControlPanel(void);
|
||||
void *ASIOFuture(long selector, void *params);
|
||||
ASIOError ASIOOutputReady(void);
|
||||
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __ASIO_H
|
||||
#define __ASIO_H
|
||||
|
||||
// force 4 byte alignment
|
||||
#if defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
#pragma pack(push,4)
|
||||
#elif PRAGMA_ALIGN_SUPPORTED
|
||||
#pragma options align = native
|
||||
#endif
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Type definitions
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// number of samples data type is 64 bit integer
|
||||
#if NATIVE_INT64
|
||||
typedef long long int ASIOSamples;
|
||||
#else
|
||||
typedef struct ASIOSamples {
|
||||
unsigned long hi;
|
||||
unsigned long lo;
|
||||
} ASIOSamples;
|
||||
#endif
|
||||
|
||||
// Timestamp data type is 64 bit integer,
|
||||
// Time format is Nanoseconds.
|
||||
#if NATIVE_INT64
|
||||
typedef long long int ASIOTimeStamp ;
|
||||
#else
|
||||
typedef struct ASIOTimeStamp {
|
||||
unsigned long hi;
|
||||
unsigned long lo;
|
||||
} ASIOTimeStamp;
|
||||
#endif
|
||||
|
||||
// Samplerates are expressed in IEEE 754 64 bit double float,
|
||||
// native format as host computer
|
||||
#if IEEE754_64FLOAT
|
||||
typedef double ASIOSampleRate;
|
||||
#else
|
||||
typedef struct ASIOSampleRate {
|
||||
char ieee[8];
|
||||
} ASIOSampleRate;
|
||||
#endif
|
||||
|
||||
// Boolean values are expressed as long
|
||||
typedef long ASIOBool;
|
||||
enum {
|
||||
ASIOFalse = 0,
|
||||
ASIOTrue = 1
|
||||
};
|
||||
|
||||
// Sample Types are expressed as long
|
||||
typedef long ASIOSampleType;
|
||||
enum {
|
||||
ASIOSTInt16MSB = 0,
|
||||
ASIOSTInt24MSB = 1, // used for 20 bits as well
|
||||
ASIOSTInt32MSB = 2,
|
||||
ASIOSTFloat32MSB = 3, // IEEE 754 32 bit float
|
||||
ASIOSTFloat64MSB = 4, // IEEE 754 64 bit double float
|
||||
|
||||
// these are used for 32 bit data buffer, with different alignment of the data inside
|
||||
// 32 bit PCI bus systems can be more easily used with these
|
||||
ASIOSTInt32MSB16 = 8, // 32 bit data with 18 bit alignment
|
||||
ASIOSTInt32MSB18 = 9, // 32 bit data with 18 bit alignment
|
||||
ASIOSTInt32MSB20 = 10, // 32 bit data with 20 bit alignment
|
||||
ASIOSTInt32MSB24 = 11, // 32 bit data with 24 bit alignment
|
||||
|
||||
ASIOSTInt16LSB = 16,
|
||||
ASIOSTInt24LSB = 17, // used for 20 bits as well
|
||||
ASIOSTInt32LSB = 18,
|
||||
ASIOSTFloat32LSB = 19, // IEEE 754 32 bit float, as found on Intel x86 architecture
|
||||
ASIOSTFloat64LSB = 20, // IEEE 754 64 bit double float, as found on Intel x86 architecture
|
||||
|
||||
// these are used for 32 bit data buffer, with different alignment of the data inside
|
||||
// 32 bit PCI bus systems can more easily used with these
|
||||
ASIOSTInt32LSB16 = 24, // 32 bit data with 18 bit alignment
|
||||
ASIOSTInt32LSB18 = 25, // 32 bit data with 18 bit alignment
|
||||
ASIOSTInt32LSB20 = 26, // 32 bit data with 20 bit alignment
|
||||
ASIOSTInt32LSB24 = 27 // 32 bit data with 24 bit alignment
|
||||
};
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Error codes
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
typedef long ASIOError;
|
||||
enum {
|
||||
ASE_OK = 0, // This value will be returned whenever the call succeeded
|
||||
ASE_SUCCESS = 0x3f4847a0, // unique success return value for ASIOFuture calls
|
||||
ASE_NotPresent = -1000, // hardware input or output is not present or available
|
||||
ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function)
|
||||
ASE_InvalidParameter, // input parameter invalid
|
||||
ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode
|
||||
ASE_SPNotAdvancing, // hardware is not running when sample position is inquired
|
||||
ASE_NoClock, // sample clock or rate cannot be determined or is not present
|
||||
ASE_NoMemory // not enough memory for completing the request
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Time Info support
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
typedef struct ASIOTimeCode
|
||||
{
|
||||
double speed; // speed relation (fraction of nominal speed)
|
||||
// optional; set to 0. or 1. if not supported
|
||||
ASIOSamples timeCodeSamples; // time in samples
|
||||
unsigned long flags; // some information flags (see below)
|
||||
char future[64];
|
||||
} ASIOTimeCode;
|
||||
|
||||
typedef enum ASIOTimeCodeFlags
|
||||
{
|
||||
kTcValid = 1,
|
||||
kTcRunning = 1 << 1,
|
||||
kTcReverse = 1 << 2,
|
||||
kTcOnspeed = 1 << 3,
|
||||
kTcStill = 1 << 4,
|
||||
|
||||
kTcSpeedValid = 1 << 8
|
||||
} ASIOTimeCodeFlags;
|
||||
|
||||
typedef struct AsioTimeInfo
|
||||
{
|
||||
double speed; // absolute speed (1. = nominal)
|
||||
ASIOTimeStamp systemTime; // system time related to samplePosition, in nanoseconds
|
||||
// on mac, must be derived from Microseconds() (not UpTime()!)
|
||||
// on windows, must be derived from timeGetTime()
|
||||
ASIOSamples samplePosition;
|
||||
ASIOSampleRate sampleRate; // current rate
|
||||
unsigned long flags; // (see below)
|
||||
char reserved[12];
|
||||
} AsioTimeInfo;
|
||||
|
||||
typedef enum AsioTimeInfoFlags
|
||||
{
|
||||
kSystemTimeValid = 1, // must always be valid
|
||||
kSamplePositionValid = 1 << 1, // must always be valid
|
||||
kSampleRateValid = 1 << 2,
|
||||
kSpeedValid = 1 << 3,
|
||||
|
||||
kSampleRateChanged = 1 << 4,
|
||||
kClockSourceChanged = 1 << 5
|
||||
} AsioTimeInfoFlags;
|
||||
|
||||
typedef struct ASIOTime // both input/output
|
||||
{
|
||||
long reserved[4]; // must be 0
|
||||
struct AsioTimeInfo timeInfo; // required
|
||||
struct ASIOTimeCode timeCode; // optional, evaluated if (timeCode.flags & kTcValid)
|
||||
} ASIOTime;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
using time info:
|
||||
it is recommended to use the new method with time info even if the asio
|
||||
device does not support timecode; continuous calls to ASIOGetSamplePosition
|
||||
and ASIOGetSampleRate are avoided, and there is a more defined relationship
|
||||
between callback time and the time info.
|
||||
|
||||
see the example below.
|
||||
to initiate time info mode, after you have received the callbacks pointer in
|
||||
ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo
|
||||
as the argument. if this returns 1, host has accepted time info mode.
|
||||
now host expects the new callback bufferSwitchTimeInfo to be used instead
|
||||
of the old bufferSwitch method. the ASIOTime structure is assumed to be valid
|
||||
and accessible until the callback returns.
|
||||
|
||||
using time code:
|
||||
if the device supports reading time code, it will call host's asioMessage callback
|
||||
with kAsioSupportsTimeCode as the selector. it may then fill the according
|
||||
fields and set the kTcValid flag.
|
||||
host will call the future method with the kAsioEnableTimeCodeRead selector when
|
||||
it wants to enable or disable tc reading by the device. you should also support
|
||||
the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example).
|
||||
|
||||
note:
|
||||
the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions.
|
||||
as a matter of convention, the relationship between the sample
|
||||
position counter and the time code at buffer switch time is
|
||||
(ignoring offset between tc and sample pos when tc is running):
|
||||
|
||||
on input: sample 0 -> input buffer sample 0 -> time code 0
|
||||
on output: sample 0 -> output buffer sample 0 -> time code 0
|
||||
|
||||
this means that for 'real' calculations, one has to take into account
|
||||
the according latencies.
|
||||
|
||||
example:
|
||||
|
||||
ASIOTime asioTime;
|
||||
|
||||
in createBuffers()
|
||||
{
|
||||
FMOD_memset(&asioTime, 0, sizeof(ASIOTime));
|
||||
AsioTimeInfo* ti = &asioTime.timeInfo;
|
||||
ti->sampleRate = theSampleRate;
|
||||
ASIOTimeCode* tc = &asioTime.timeCode;
|
||||
tc->speed = 1.;
|
||||
timeInfoMode = false;
|
||||
canTimeCode = false;
|
||||
if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1)
|
||||
{
|
||||
timeInfoMode = true;
|
||||
#if kCanTimeCode
|
||||
if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1)
|
||||
canTimeCode = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void switchBuffers(long doubleBufferIndex, bool processNow)
|
||||
{
|
||||
if(timeInfoMode)
|
||||
{
|
||||
AsioTimeInfo* ti = &asioTime.timeInfo;
|
||||
ti->flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid;
|
||||
ti->systemTime = theNanoSeconds;
|
||||
ti->samplePosition = theSamplePosition;
|
||||
if(ti->sampleRate != theSampleRate)
|
||||
ti->flags |= kSampleRateChanged;
|
||||
ti->sampleRate = theSampleRate;
|
||||
|
||||
#if kCanTimeCode
|
||||
if(canTimeCode && timeCodeEnabled)
|
||||
{
|
||||
ASIOTimeCode* tc = &asioTime.timeCode;
|
||||
tc->timeCodeSamples = tcSamples; // tc in samples
|
||||
tc->flags = kTcValid | kTcRunning | kTcOnspeed; // if so...
|
||||
}
|
||||
ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);
|
||||
#else
|
||||
callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse);
|
||||
}
|
||||
|
||||
ASIOError ASIOFuture(long selector, void *params)
|
||||
{
|
||||
switch(selector)
|
||||
{
|
||||
case kAsioEnableTimeCodeRead:
|
||||
timeCodeEnabled = true;
|
||||
return ASE_SUCCESS;
|
||||
case kAsioDisableTimeCodeRead:
|
||||
timeCodeEnabled = false;
|
||||
return ASE_SUCCESS;
|
||||
case kAsioCanTimeInfo:
|
||||
return ASE_SUCCESS;
|
||||
#if kCanTimeCode
|
||||
case kAsioCanTimeCode:
|
||||
return ASE_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
return ASE_NotPresent;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// application's audio stream handler callbacks
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
typedef struct ASIOCallbacks
|
||||
{
|
||||
void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);
|
||||
// bufferSwitch indicates that both input and output are to be processed.
|
||||
// the current buffer half index (0 for A, 1 for B) determines
|
||||
// - the output buffer that the host should start to fill. the other buffer
|
||||
// will be passed to output hardware regardless of whether it got filled
|
||||
// in time or not.
|
||||
// - the input buffer that is now filled with incoming data. Note that
|
||||
// because of the synchronicity of i/o, the input always has at
|
||||
// least one buffer latency in relation to the output.
|
||||
// directProcess suggests to the host whether it should immedeately
|
||||
// start processing (directProcess == ASIOTrue), or whether its process
|
||||
// should be deferred because the call comes from a very low level
|
||||
// (for instance, a high level priority interrupt), and direct processing
|
||||
// would cause timing instabilities for the rest of the system. If in doubt,
|
||||
// directProcess should be set to ASIOFalse.
|
||||
// Note: bufferSwitch may be called at interrupt time for highest efficiency.
|
||||
|
||||
void (*sampleRateDidChange) (ASIOSampleRate sRate);
|
||||
// gets called when the AudioStreamIO detects a sample rate change
|
||||
// If sample rate is unknown, 0 is passed (for instance, clock loss
|
||||
// when externally synchronized).
|
||||
|
||||
long (*asioMessage) (long selector, long value, void* message, double* opt);
|
||||
// generic callback for various purposes, see selectors below.
|
||||
// note this is only present if the asio version is 2 or higher
|
||||
|
||||
ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);
|
||||
// new callback with time info. makes ASIOGetSamplePosition() and various
|
||||
// calls to ASIOGetSampleRate obsolete,
|
||||
// and allows for timecode sync etc. to be preferred; will be used if
|
||||
// the driver calls asioMessage with selector kAsioSupportsTimeInfo.
|
||||
} ASIOCallbacks;
|
||||
|
||||
// asioMessage selectors
|
||||
enum
|
||||
{
|
||||
kAsioSelectorSupported = 1, // selector in <value>, returns 1L if supported,
|
||||
// 0 otherwise
|
||||
kAsioEngineVersion, // returns engine (host) asio implementation version,
|
||||
// 2 or higher
|
||||
kAsioResetRequest, // request driver reset. if accepted, this
|
||||
// will close the driver (ASIO_Exit() ) and
|
||||
// re-open it again (ASIO_Init() etc). some
|
||||
// drivers need to reconfigure for instance
|
||||
// when the sample rate changes, or some basic
|
||||
// changes have been made in ASIO_ControlPanel().
|
||||
// returns 1L; note the request is merely passed
|
||||
// to the application, there is no way to determine
|
||||
// if it gets accepted at this time (but it usually
|
||||
// will be).
|
||||
kAsioBufferSizeChange, // not yet supported, will currently always return 0L.
|
||||
// for now, use kAsioResetRequest instead.
|
||||
// once implemented, the new buffer size is expected
|
||||
// in <value>, and on success returns 1L
|
||||
kAsioResyncRequest, // the driver went out of sync, such that
|
||||
// the timestamp is no longer valid. this
|
||||
// is a request to re-start the engine and
|
||||
// slave devices (sequencer). returns 1 for ok,
|
||||
// 0 if not supported.
|
||||
kAsioLatenciesChanged, // the drivers latencies have changed. The engine
|
||||
// will refetch the latencies.
|
||||
kAsioSupportsTimeInfo, // if host returns true here, it will expect the
|
||||
// callback bufferSwitchTimeInfo to be called instead
|
||||
// of bufferSwitch
|
||||
kAsioSupportsTimeCode, // supports time code reading/writing
|
||||
|
||||
kAsioSupportsInputMonitor, // supports input monitoring
|
||||
|
||||
kAsioNumMessageSelectors
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// (De-)Construction
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
typedef struct ASIODriverInfo
|
||||
{
|
||||
long asioVersion; // currently, 2
|
||||
long driverVersion; // driver specific
|
||||
char name[32];
|
||||
char errorMessage[124];
|
||||
void *sysRef; // on input: system reference
|
||||
// (Windows: application main window handle, Mac & SGI: 0)
|
||||
} ASIODriverInfo;
|
||||
|
||||
ASIOError ASIOInit(ASIODriverInfo *info);
|
||||
/* Purpose:
|
||||
Initialize the AudioStreamIO.
|
||||
Parameter:
|
||||
info: pointer to an ASIODriver structure:
|
||||
- asioVersion:
|
||||
- on input, the host version. *** Note *** this is 0 for earlier asio
|
||||
implementations, and the asioMessage callback is implemeted
|
||||
only if asioVersion is 2 or greater. sorry but due to a design fault
|
||||
the driver doesn't have access to the host version in ASIOInit :-(
|
||||
added selector for host (engine) version in the asioMessage callback
|
||||
so we're ok from now on.
|
||||
- on return, asio implementation version.
|
||||
older versions are 1
|
||||
if you support this version (namely, ASIO_outputReady() )
|
||||
this should be 2 or higher. also see the note in
|
||||
ASIO_getTimeStamp() !
|
||||
- version: on return, the driver version (format is driver specific)
|
||||
- name: on return, a null-terminated string containing the driver's name
|
||||
- error message: on return, should contain a user message describing
|
||||
the type of error that occured during ASIOInit(), if any.
|
||||
- sysRef: platform specific
|
||||
Returns:
|
||||
If neither input nor output is present ASE_NotPresent
|
||||
will be returned.
|
||||
ASE_NoMemory, ASE_HWMalfunction are other possible error conditions
|
||||
*/
|
||||
|
||||
ASIOError ASIOExit(void);
|
||||
/* Purpose:
|
||||
Terminates the AudioStreamIO.
|
||||
Parameter:
|
||||
None.
|
||||
Returns:
|
||||
If neither input nor output is present ASE_NotPresent
|
||||
will be returned.
|
||||
Notes: this implies ASIOStop() and ASIODisposeBuffers(),
|
||||
meaning that no host callbacks must be accessed after ASIOExit().
|
||||
*/
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Start/Stop
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
ASIOError ASIOStart(void);
|
||||
/* Purpose:
|
||||
Start input and output processing synchronously.
|
||||
This will
|
||||
- reset the sample counter to zero
|
||||
- start the hardware (both input and output)
|
||||
The first call to the hosts' bufferSwitch(index == 0) then tells
|
||||
the host to read from input buffer A (index 0), and start
|
||||
processing to output buffer A while output buffer B (which
|
||||
has been filled by the host prior to calling ASIOStart())
|
||||
is possibly sounding (see also ASIOGetLatencies())
|
||||
Parameter:
|
||||
None.
|
||||
Returns:
|
||||
If neither input nor output is present, ASE_NotPresent
|
||||
will be returned.
|
||||
If the hardware fails to start, ASE_HWMalfunction will be returned.
|
||||
Notes:
|
||||
There is no restriction on the time that ASIOStart() takes
|
||||
to perform (that is, it is not considered a realtime trigger).
|
||||
*/
|
||||
|
||||
ASIOError ASIOStop(void);
|
||||
/* Purpose:
|
||||
Stops input and output processing altogether.
|
||||
Parameter:
|
||||
None.
|
||||
Returns:
|
||||
If neither input nor output is present ASE_NotPresent
|
||||
will be returned.
|
||||
Notes:
|
||||
On return from ASIOStop(), the driver must in no
|
||||
case call the hosts' bufferSwitch() routine.
|
||||
*/
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Inquiry methods and sample rate
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);
|
||||
/* Purpose:
|
||||
Returns number of individual input/output channels.
|
||||
Parameter:
|
||||
numInputChannels will hold the number of available input channels
|
||||
numOutputChannels will hold the number of available output channels
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
If only inputs, or only outputs are available, the according
|
||||
other parameter will be zero, and ASE_OK is returned.
|
||||
*/
|
||||
|
||||
ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);
|
||||
/* Purpose:
|
||||
Returns the input and output latencies. This includes
|
||||
device specific delays, like FIFOs etc.
|
||||
Parameter:
|
||||
inputLatency will hold the 'age' of the first sample frame
|
||||
in the input buffer when the hosts reads it in bufferSwitch()
|
||||
(this is theoretical, meaning it does not include the overhead
|
||||
and delay between the actual physical switch, and the time
|
||||
when bufferSitch() enters).
|
||||
This will usually be the size of one block in sample frames, plus
|
||||
device specific latencies.
|
||||
|
||||
outputLatency will specify the time between the buffer switch,
|
||||
and the time when the next play buffer will start to sound.
|
||||
The next play buffer is defined as the one the host starts
|
||||
processing after (or at) bufferSwitch(), indicated by the
|
||||
index parameter (0 for buffer A, 1 for buffer B).
|
||||
It will usually be either one block, if the host writes directly
|
||||
to a dma buffer, or two or more blocks if the buffer is 'latched' by
|
||||
the driver. As an example, on ASIOStart(), the host will have filled
|
||||
the play buffer at index 1 already; when it gets the callback (with
|
||||
the parameter index == 0), this tells it to read from the input
|
||||
buffer 0, and start to fill the play buffer 0 (assuming that now
|
||||
play buffer 1 is already sounding). In this case, the output
|
||||
latency is one block. If the driver decides to copy buffer 1
|
||||
at that time, and pass it to the hardware at the next slot (which
|
||||
is most commonly done, but should be avoided), the output latency
|
||||
becomes two blocks instead, resulting in a total i/o latency of at least
|
||||
3 blocks. As memory access is the main bottleneck in native dsp processing,
|
||||
and to acheive less latency, it is highly recommended to try to avoid
|
||||
copying (this is also why the driver is the owner of the buffers). To
|
||||
summarize, the minimum i/o latency can be acheived if the input buffer
|
||||
is processed by the host into the output buffer which will physically
|
||||
start to sound on the next time slice. Also note that the host expects
|
||||
the bufferSwitch() callback to be accessed for each time slice in order
|
||||
to retain sync, possibly recursively; if it fails to process a block in
|
||||
time, it will suspend its operation for some time in order to recover.
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
*/
|
||||
|
||||
ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
|
||||
/* Purpose:
|
||||
Returns min, max, and preferred buffer sizes for input/output
|
||||
Parameter:
|
||||
minSize will hold the minimum buffer size
|
||||
maxSize will hold the maxium possible buffer size
|
||||
preferredSize will hold the preferred buffer size (a size which
|
||||
best fits performance and hardware requirements)
|
||||
granularity will hold the granularity at which buffer sizes
|
||||
may differ. Usually, the buffer size will be a power of 2;
|
||||
in this case, granularity will hold -1 on return, signalling
|
||||
possible buffer sizes starting from minSize, increased in
|
||||
powers of 2 up to maxSize.
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
When minimum and maximum buffer size are equal,
|
||||
the preferred buffer size has to be the same value as well; granularity
|
||||
should be 0 in this case.
|
||||
*/
|
||||
|
||||
ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);
|
||||
/* Purpose:
|
||||
Inquires the hardware for the available sample rates.
|
||||
Parameter:
|
||||
sampleRate is the rate in question.
|
||||
Returns:
|
||||
If the inquired sample rate is not supported, ASE_NoClock will be returned.
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
*/
|
||||
ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);
|
||||
/* Purpose:
|
||||
Get the current sample Rate.
|
||||
Parameter:
|
||||
currentRate will hold the current sample rate on return.
|
||||
Returns:
|
||||
If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned.
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
*/
|
||||
|
||||
ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);
|
||||
/* Purpose:
|
||||
Set the hardware to the requested sample Rate. If sampleRate == 0,
|
||||
enable external sync.
|
||||
Parameter:
|
||||
sampleRate: on input, the requested rate
|
||||
Returns:
|
||||
If sampleRate is unknown ASE_NoClock will be returned.
|
||||
If the current clock is external, and sampleRate is != 0,
|
||||
ASE_InvalidMode will be returned
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
*/
|
||||
|
||||
typedef struct ASIOClockSource
|
||||
{
|
||||
long index; // as used for ASIOSetClockSource()
|
||||
long associatedChannel; // for instance, S/PDIF or AES/EBU
|
||||
long associatedGroup; // see channel groups (ASIOGetChannelInfo())
|
||||
ASIOBool isCurrentSource; // ASIOTrue if this is the current clock source
|
||||
char name[32]; // for user selection
|
||||
} ASIOClockSource;
|
||||
|
||||
ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);
|
||||
/* Purpose:
|
||||
Get the available external audio clock sources
|
||||
Parameter:
|
||||
clocks points to an array of ASIOClockSource structures:
|
||||
- index: this is used to identify the clock source
|
||||
when ASIOSetClockSource() is accessed, should be
|
||||
an index counting from zero
|
||||
- associatedInputChannel: the first channel of an associated
|
||||
input group, if any.
|
||||
- associatedGroup: the group index of that channel.
|
||||
groups of channels are defined to seperate for
|
||||
instance analog, S/PDIF, AES/EBU, ADAT connectors etc,
|
||||
when present simultaniously. Note that associated channel
|
||||
is enumerated according to numInputs/numOutputs, means it
|
||||
is independant from a group (see also ASIOGetChannelInfo())
|
||||
inputs are associated to a clock if the physical connection
|
||||
transfers both data and clock (like S/PDIF, AES/EBU, or
|
||||
ADAT inputs). if there is no input channel associated with
|
||||
the clock source (like Word Clock, or internal oscillator), both
|
||||
associatedChannel and associatedGroup should be set to -1.
|
||||
- isCurrentSource: on exit, ASIOTrue if this is the current clock
|
||||
source, ASIOFalse else
|
||||
- name: a null-terminated string for user selection of the available sources.
|
||||
numSources:
|
||||
on input: the number of allocated array members
|
||||
on output: the number of available clock sources, at least
|
||||
1 (internal clock generator).
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
*/
|
||||
|
||||
ASIOError ASIOSetClockSource(long index);
|
||||
/* Purpose:
|
||||
Set the audio clock source
|
||||
Parameter:
|
||||
index as obtained from an inquiry to ASIOGetClockSources()
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
If the clock can not be selected because an input channel which
|
||||
carries the current clock source is active, ASE_InvalidMode
|
||||
*may* be returned (this depends on the properties of the driver
|
||||
and/or hardware).
|
||||
Notes:
|
||||
Should *not* return ASE_NoClock if there is no clock signal present
|
||||
at the selected source; this will be inquired via ASIOGetSampleRate().
|
||||
It should call the host callback procedure sampleRateHasChanged(),
|
||||
if the switch causes a sample rate change, or if no external clock
|
||||
is present at the selected source.
|
||||
*/
|
||||
|
||||
ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
|
||||
/* Purpose:
|
||||
Inquires the sample position/time stamp pair.
|
||||
Parameter:
|
||||
sPos will hold the sample position on return. The sample
|
||||
position is reset to zero when ASIOStart() gets called.
|
||||
tStamp will hold the system time when the sample position
|
||||
was latched.
|
||||
Returns:
|
||||
If no input/output is present, ASE_NotPresent will be returned.
|
||||
If there is no clock, ASE_SPNotAdvancing will be returned.
|
||||
Notes:
|
||||
|
||||
in order to be able to synchronise properly,
|
||||
the sample position / time stamp pair must refer to the current block,
|
||||
that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch()
|
||||
callback and expect the time for the current block. thus, when requested
|
||||
in the very first bufferSwitch after ASIO_Start(), the sample position
|
||||
should be zero, and the time stamp should refer to the very time where
|
||||
the stream was started. it also means that the sample position must be
|
||||
block aligned. the driver must ensure proper interpolation if the system
|
||||
time can not be determined for the block position. the driver is responsible
|
||||
for precise time stamps as it usually has most direct access to lower
|
||||
level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies()
|
||||
are essential for precise media synchronization!
|
||||
*/
|
||||
|
||||
typedef struct ASIOChannelInfo
|
||||
{
|
||||
long channel; // on input, channel index
|
||||
ASIOBool isInput; // on input
|
||||
ASIOBool isActive; // on exit
|
||||
long channelGroup; // dto
|
||||
ASIOSampleType type; // dto
|
||||
char name[32]; // dto
|
||||
} ASIOChannelInfo;
|
||||
|
||||
ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);
|
||||
/* Purpose:
|
||||
retreive information about the nature of a channel
|
||||
Parameter:
|
||||
info: pointer to a ASIOChannelInfo structure with
|
||||
- channel: on input, the channel index of the channel in question.
|
||||
- isInput: on input, ASIOTrue if info for an input channel is
|
||||
requested, else output
|
||||
- channelGroup: on return, the channel group that the channel
|
||||
belongs to. For drivers which support different types of
|
||||
channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,
|
||||
there should be a reasonable grouping of these types. Groups
|
||||
are always independant form a channel index, that is, a channel
|
||||
index always counts from 0 to numInputs/numOutputs regardless
|
||||
of the group it may belong to.
|
||||
There will always be at least one group (group 0). Please
|
||||
also note that by default, the host may decide to activate
|
||||
channels 0 and 1; thus, these should belong to the most
|
||||
useful type (analog i/o, if present).
|
||||
- type: on return, contains the sample type of the channel
|
||||
- isActive: on return, ASIOTrue if channel is active as it was
|
||||
installed by ASIOCreateBuffers(), ASIOFalse else
|
||||
- name: describing the type of channel in question. Used to allow
|
||||
for user selection, and enabling of specific channels. examples:
|
||||
"Analog In", "SPDIF Out" etc
|
||||
Returns:
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
If possible, the string should be organised such that the first
|
||||
characters are most significantly describing the nature of the
|
||||
port, to allow for identification even if the view showing the
|
||||
port name is too small to display more than 8 characters, for
|
||||
instance.
|
||||
*/
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Buffer preparation
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
typedef struct ASIOBufferInfo
|
||||
{
|
||||
ASIOBool isInput; // on input: ASIOTrue: input, else output
|
||||
long channelNum; // on input: channel index
|
||||
void *buffers[2]; // on output: double buffer addresses
|
||||
} ASIOBufferInfo;
|
||||
|
||||
ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
|
||||
long bufferSize, ASIOCallbacks *callbacks);
|
||||
|
||||
/* Purpose:
|
||||
Allocates input/output buffers for all input and output channels to be activated.
|
||||
Parameter:
|
||||
bufferInfos is a pointer to an array of ASIOBufferInfo structures:
|
||||
- isInput: on input, ASIOTrue if the buffer is to be allocated
|
||||
for an input, output buffer else
|
||||
- channelNum: on input, the index of the channel in question
|
||||
(counting from 0)
|
||||
- buffers: on exit, 2 pointers to the halves of the channels' double-buffer.
|
||||
the size of the buffer(s) of course depend on both the ASIOSampleType
|
||||
as obtained from ASIOGetChannelInfo(), and bufferSize
|
||||
numChannels is the sum of all input and output channels to be created;
|
||||
thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo
|
||||
structures.
|
||||
bufferSize selects one of the possible buffer sizes as obtained from
|
||||
ASIOGetBufferSizes().
|
||||
callbacks is a pointer to an ASIOCallbacks structure.
|
||||
Returns:
|
||||
If not enough memory is available ASE_NoMemory will be returned.
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
If bufferSize is not supported, or one or more of the bufferInfos elements
|
||||
contain invalid settings, ASE_InvalidMode will be returned.
|
||||
Notes:
|
||||
If individual channel selection is not possible but requested,
|
||||
the driver has to handle this. namely, bufferSwitch() will only
|
||||
have filled buffers of enabled outputs. If possible, processing
|
||||
and buss activities overhead should be avoided for channels which
|
||||
were not enabled here.
|
||||
*/
|
||||
|
||||
ASIOError ASIODisposeBuffers(void);
|
||||
/* Purpose:
|
||||
Releases all buffers for the device.
|
||||
Parameter:
|
||||
None.
|
||||
Returns:
|
||||
If no buffer were ever prepared, ASE_InvalidMode will be returned.
|
||||
If no input/output is present ASE_NotPresent will be returned.
|
||||
Notes:
|
||||
This implies ASIOStop().
|
||||
*/
|
||||
|
||||
ASIOError ASIOControlPanel(void);
|
||||
/* Purpose:
|
||||
request the driver to start a control panel component
|
||||
for device specific user settings. This will not be
|
||||
accessed on some platforms (where the component is accessed
|
||||
instead).
|
||||
Parameter:
|
||||
None.
|
||||
Returns:
|
||||
If no panel is available ASE_NotPresent will be returned.
|
||||
Actually, the return code is ignored.
|
||||
Notes:
|
||||
if the user applied settings which require a re-configuration
|
||||
of parts or all of the enigine and/or driver (such as a change of
|
||||
the block size), the asioMessage callback can be used (see
|
||||
ASIO_Callbacks).
|
||||
*/
|
||||
|
||||
ASIOError ASIOFuture(long selector, void *params);
|
||||
/* Purpose:
|
||||
various
|
||||
Parameter:
|
||||
selector: operation Code as to be defined. zero is reserved for
|
||||
testing purposes.
|
||||
params: depends on the selector; usually pointer to a structure
|
||||
for passing and retreiving any type and amount of parameters.
|
||||
Returns:
|
||||
the return value is also selector dependant. if the selector
|
||||
is unknown, ASE_InvalidParameter should be returned to prevent
|
||||
further calls with this selector. on success, ASE_SUCCESS
|
||||
must be returned (note: ASE_OK is *not* sufficient!)
|
||||
Notes:
|
||||
see selectors defined below.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
kAsioEnableTimeCodeRead = 1, // no arguments
|
||||
kAsioDisableTimeCodeRead, // no arguments
|
||||
kAsioSetInputMonitor, // ASIOInputMonitor* in params
|
||||
kAsioTransport, // ASIOTransportParameters* in params
|
||||
kAsioSetInputGain, // ASIOChannelControls* in params, apply gain
|
||||
kAsioGetInputMeter, // ASIOChannelControls* in params, fill meter
|
||||
kAsioSetOutputGain, // ASIOChannelControls* in params, apply gain
|
||||
kAsioGetOutputMeter, // ASIOChannelControls* in params, fill meter
|
||||
kAsioCanInputMonitor, // no arguments for kAsioCanXXX selectors
|
||||
kAsioCanTimeInfo,
|
||||
kAsioCanTimeCode,
|
||||
kAsioCanTransport,
|
||||
kAsioCanInputGain,
|
||||
kAsioCanInputMeter,
|
||||
kAsioCanOutputGain,
|
||||
kAsioCanOutputMeter
|
||||
};
|
||||
|
||||
typedef struct ASIOInputMonitor
|
||||
{
|
||||
long input; // this input was set to monitor (or off), -1: all
|
||||
long output; // suggested output for monitoring the input (if so)
|
||||
long gain; // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB)
|
||||
ASIOBool state; // ASIOTrue => on, ASIOFalse => off
|
||||
long pan; // suggested pan, 0 => all left, 0x7fffffff => right
|
||||
} ASIOInputMonitor;
|
||||
|
||||
typedef struct ASIOChannelControls
|
||||
{
|
||||
long channel; // on input, channel index
|
||||
ASIOBool isInput; // on input
|
||||
long gain; // on input, ranges 0 thru 0x7fffffff
|
||||
long meter; // on return, ranges 0 thru 0x7fffffff
|
||||
char future[32];
|
||||
} ASIOChannelControls;
|
||||
|
||||
typedef struct ASIOTransportParameters
|
||||
{
|
||||
long command; // see enum below
|
||||
ASIOSamples samplePosition;
|
||||
long track;
|
||||
long trackSwitches[16]; // 512 tracks on/off
|
||||
char future[64];
|
||||
} ASIOTransportParameters;
|
||||
|
||||
enum
|
||||
{
|
||||
kTransStart = 1,
|
||||
kTransStop,
|
||||
kTransLocate, // to samplePosition
|
||||
kTransPunchIn,
|
||||
kTransPunchOut,
|
||||
kTransArmOn, // track
|
||||
kTransArmOff, // track
|
||||
kTransMonitorOn, // track
|
||||
kTransMonitorOff, // track
|
||||
kTransArm, // trackSwitches
|
||||
kTransMonitor // trackSwitches
|
||||
};
|
||||
|
||||
ASIOError ASIOOutputReady(void);
|
||||
/* Purpose:
|
||||
this tells the driver that the host has completed processing
|
||||
the output buffers. if the data format required by the hardware
|
||||
differs from the supported asio formats, but the hardware
|
||||
buffers are DMA buffers, the driver will have to convert
|
||||
the audio stream data; as the bufferSwitch callback is
|
||||
usually issued at dma block switch time, the driver will
|
||||
have to convert the *previous* host buffer, which increases
|
||||
the output latency by one block.
|
||||
when the host finds out that ASIOOutputReady() returns
|
||||
true, it will issue this call whenever it completed
|
||||
output processing. then the driver can convert the
|
||||
host data directly to the dma buffer to be played next,
|
||||
reducing output latency by one block.
|
||||
another way to look at it is, that the buffer switch is called
|
||||
in order to pass the *input* stream to the host, so that it can
|
||||
process the input into the output, and the output stream is passed
|
||||
to the driver when the host has completed its process.
|
||||
Parameter:
|
||||
None
|
||||
Returns:
|
||||
only if the above mentioned scenario is given, and a reduction
|
||||
of output latency can be acheived by this mechanism, should
|
||||
ASE_OK be returned. otherwise (and usually), ASE_NotPresent
|
||||
should be returned in order to prevent further calls to this
|
||||
function. note that the host may want to determine if it is
|
||||
to use this when the system is not yet fully initialized, so
|
||||
ASE_OK should always be returned if the mechanism makes sense.
|
||||
Notes:
|
||||
please remeber to adjust ASIOGetLatencies() according to
|
||||
whether ASIOOutputReady() was ever called or not, if your
|
||||
driver supports this scenario.
|
||||
also note that the engine may fail to call ASIO_OutputReady()
|
||||
in time in overload cases. as already mentioned, bufferSwitch
|
||||
should be called for every block regardless of whether a block
|
||||
could be processed in time.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// restore old alignment
|
||||
#if defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_ALIGN_SUPPORTED
|
||||
#pragma options align = reset
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
190
fmod/win32/src/asio/asiodrivers.cpp
Executable file
190
fmod/win32/src/asio/asiodrivers.cpp
Executable file
|
|
@ -0,0 +1,190 @@
|
|||
#include "asiodrivers.h"
|
||||
|
||||
AsioDrivers* asioDrivers = 0;
|
||||
|
||||
bool loadAsioDriver(char *name);
|
||||
|
||||
bool loadAsioDriver(char *name)
|
||||
{
|
||||
if(!asioDrivers)
|
||||
asioDrivers = new AsioDrivers();
|
||||
if(asioDrivers)
|
||||
return asioDrivers->loadDriver(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
#if MAC
|
||||
|
||||
bool resolveASIO(unsigned long aconnID);
|
||||
|
||||
AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio')
|
||||
{
|
||||
connID = -1;
|
||||
curIndex = -1;
|
||||
}
|
||||
|
||||
bool AsioDrivers::close()
|
||||
{
|
||||
removeCurrentDriver();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsioDrivers::getCurrentDriverName(char *name)
|
||||
{
|
||||
if(curIndex >= 0)
|
||||
return getName(curIndex, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
long AsioDrivers::getDriverNames(char **names, long maxDrivers)
|
||||
{
|
||||
for(long i = 0; i < getNumFragments() && i < maxDrivers; i++)
|
||||
getName(i, names[i]);
|
||||
return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers;
|
||||
}
|
||||
|
||||
bool AsioDrivers::loadDriver(char *name)
|
||||
{
|
||||
char dname[64];
|
||||
unsigned long newID;
|
||||
|
||||
for(long i = 0; i < getNumFragments(); i++)
|
||||
{
|
||||
if(getName(i, dname) && !strcmp(name, dname))
|
||||
{
|
||||
if(newInstance(i, &newID))
|
||||
{
|
||||
if(resolveASIO(newID))
|
||||
{
|
||||
if(connID != -1)
|
||||
removeInstance(curIndex, connID);
|
||||
curIndex = i;
|
||||
connID = newID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AsioDrivers::removeCurrentDriver()
|
||||
{
|
||||
if(connID != -1)
|
||||
removeInstance(curIndex, connID);
|
||||
connID = -1;
|
||||
curIndex = -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
#elif WINDOWS
|
||||
|
||||
#include "iasiodrv.h"
|
||||
|
||||
extern IASIO* theAsioDriver;
|
||||
|
||||
AsioDrivers::AsioDrivers() : AsioDriverList()
|
||||
{
|
||||
curIndex = -1;
|
||||
}
|
||||
|
||||
bool AsioDrivers::close()
|
||||
{
|
||||
AsioDriverList::close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsioDrivers::getCurrentDriverName(char *name)
|
||||
{
|
||||
if(curIndex >= 0)
|
||||
return asioGetDriverName(curIndex, name, 32) == 0 ? true : false;
|
||||
name[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
long AsioDrivers::getDriverNames(char **names, long maxDrivers)
|
||||
{
|
||||
for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++)
|
||||
asioGetDriverName(i, names[i], 32);
|
||||
return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers;
|
||||
}
|
||||
|
||||
bool AsioDrivers::loadDriver(char *name)
|
||||
{
|
||||
char dname[64];
|
||||
char curName[64];
|
||||
|
||||
for(long i = 0; i < asioGetNumDev(); i++)
|
||||
{
|
||||
if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname))
|
||||
{
|
||||
curName[0] = 0;
|
||||
getCurrentDriverName(curName); // in case we fail...
|
||||
removeCurrentDriver();
|
||||
|
||||
if(!asioOpenDriver(i, (void **)&theAsioDriver))
|
||||
{
|
||||
curIndex = i;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
theAsioDriver = 0;
|
||||
if(curName[0] && strcmp(dname, curName))
|
||||
loadDriver(curName); // try restore
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AsioDrivers::removeCurrentDriver()
|
||||
{
|
||||
if(curIndex != -1)
|
||||
asioCloseDriver(curIndex);
|
||||
curIndex = -1;
|
||||
}
|
||||
|
||||
#elif SGI || BEOS
|
||||
|
||||
#include "asiolist.h"
|
||||
|
||||
AsioDrivers::AsioDrivers()
|
||||
: AsioDriverList()
|
||||
{
|
||||
curIndex = -1;
|
||||
}
|
||||
|
||||
bool AsioDrivers::close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsioDrivers::getCurrentDriverName(char *name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long AsioDrivers::getDriverNames(char **names, long maxDrivers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AsioDrivers::loadDriver(char *name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AsioDrivers::removeCurrentDriver()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
#error implement me
|
||||
#endif
|
||||
41
fmod/win32/src/asio/asiodrivers.h
Executable file
41
fmod/win32/src/asio/asiodrivers.h
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef __AsioDrivers__
|
||||
#define __AsioDrivers__
|
||||
|
||||
#include "ginclude.h"
|
||||
|
||||
#if MAC
|
||||
#include "CodeFragments.hpp"
|
||||
|
||||
class AsioDrivers : public CodeFragments
|
||||
|
||||
#elif WINDOWS
|
||||
#include <windows.h>
|
||||
#include "asiolist.h"
|
||||
|
||||
class AsioDrivers : public AsioDriverList
|
||||
|
||||
#elif SGI || BEOS
|
||||
#include "asiolist.h"
|
||||
|
||||
class AsioDrivers : public AsioDriverList
|
||||
|
||||
#else
|
||||
#error implement me
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
AsioDrivers();
|
||||
bool close();
|
||||
|
||||
bool getCurrentDriverName(char *name);
|
||||
long getDriverNames(char **names, long maxDrivers);
|
||||
bool loadDriver(char *name);
|
||||
void removeCurrentDriver();
|
||||
long getCurrentDriverIndex() {return curIndex;}
|
||||
protected:
|
||||
unsigned long connID;
|
||||
long curIndex;
|
||||
};
|
||||
|
||||
#endif
|
||||
273
fmod/win32/src/asio/asiolist.cpp
Executable file
273
fmod/win32/src/asio/asiolist.cpp
Executable file
|
|
@ -0,0 +1,273 @@
|
|||
#include <windows.h>
|
||||
#include "iasiodrv.h"
|
||||
#include "asiolist.h"
|
||||
|
||||
#include "fmod_memory.h"
|
||||
|
||||
#define ASIODRV_DESC "description"
|
||||
#define INPROC_SERVER "InprocServer32"
|
||||
#define ASIO_PATH "software\\asio"
|
||||
#define COM_CLSID "clsid"
|
||||
|
||||
// ******************************************************************
|
||||
// Local Functions
|
||||
// ******************************************************************
|
||||
static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize)
|
||||
{
|
||||
HKEY hkEnum,hksub,hkpath;
|
||||
char databuf[512];
|
||||
LONG cr,rc = -1;
|
||||
DWORD datatype,datasize;
|
||||
DWORD index;
|
||||
OFSTRUCT ofs;
|
||||
HFILE hfile;
|
||||
BOOL found = FALSE;
|
||||
|
||||
CharLowerBuff(clsidstr,(DWORD)strlen(clsidstr));
|
||||
if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) {
|
||||
|
||||
index = 0;
|
||||
while (cr == ERROR_SUCCESS && !found) {
|
||||
cr = RegEnumKey(hkEnum,index++,(LPTSTR)databuf,512);
|
||||
if (cr == ERROR_SUCCESS) {
|
||||
CharLowerBuff(databuf,(DWORD)strlen(databuf));
|
||||
if (!(strcmp(databuf,clsidstr))) {
|
||||
if ((cr = RegOpenKeyEx(hkEnum,(LPCTSTR)databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
|
||||
if ((cr = RegOpenKeyEx(hksub,(LPCTSTR)INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) {
|
||||
datatype = REG_SZ; datasize = (DWORD)dllpathsize;
|
||||
cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize);
|
||||
if (cr == ERROR_SUCCESS) {
|
||||
FMOD_memset(&ofs,0,sizeof(OFSTRUCT));
|
||||
ofs.cBytes = sizeof(OFSTRUCT);
|
||||
hfile = OpenFile(dllpath,&ofs,OF_EXIST);
|
||||
if (hfile) rc = 0;
|
||||
}
|
||||
RegCloseKey(hkpath);
|
||||
}
|
||||
RegCloseKey(hksub);
|
||||
}
|
||||
found = TRUE; // break out
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hkEnum);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv)
|
||||
{
|
||||
HKEY hksub;
|
||||
char databuf[256];
|
||||
char dllpath[MAXPATHLEN];
|
||||
WORD wData[100];
|
||||
CLSID clsid;
|
||||
DWORD datatype,datasize;
|
||||
LONG cr,rc;
|
||||
|
||||
if (!lpdrv) {
|
||||
if ((cr = RegOpenKeyEx(hkey,(LPCTSTR)keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) {
|
||||
|
||||
datatype = REG_SZ; datasize = 256;
|
||||
cr = RegQueryValueEx(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize);
|
||||
if (cr == ERROR_SUCCESS) {
|
||||
rc = findDrvPath (databuf,dllpath,MAXPATHLEN);
|
||||
if (rc == 0) {
|
||||
lpdrv = FMOD_Object_Calloc(ASIODRVSTRUCT);
|
||||
if (lpdrv) {
|
||||
FMOD_memset(lpdrv,0,sizeof(ASIODRVSTRUCT));
|
||||
lpdrv->drvID = drvID;
|
||||
MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100);
|
||||
if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) {
|
||||
FMOD_memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID));
|
||||
}
|
||||
|
||||
datatype = REG_SZ; datasize = 256;
|
||||
cr = RegQueryValueEx(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize);
|
||||
if (cr == ERROR_SUCCESS) {
|
||||
strcpy(lpdrv->drvname,databuf);
|
||||
}
|
||||
else strcpy(lpdrv->drvname,keyname);
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hksub);
|
||||
}
|
||||
}
|
||||
else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next);
|
||||
|
||||
return lpdrv;
|
||||
}
|
||||
|
||||
static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv)
|
||||
{
|
||||
IASIO *iasio;
|
||||
|
||||
if (lpdrv != 0) {
|
||||
deleteDrvStruct(lpdrv->next);
|
||||
if (lpdrv->asiodrv) {
|
||||
iasio = (IASIO *)lpdrv->asiodrv;
|
||||
iasio->Release();
|
||||
}
|
||||
FMOD_Memory_Free(lpdrv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv)
|
||||
{
|
||||
while (lpdrv) {
|
||||
if (lpdrv->drvID == drvID) return lpdrv;
|
||||
lpdrv = lpdrv->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
// ******************************************************************
|
||||
// AsioDriverList
|
||||
// ******************************************************************
|
||||
AsioDriverList::AsioDriverList ()
|
||||
{
|
||||
HKEY hkEnum = 0;
|
||||
char keyname[MAXDRVNAMELEN];
|
||||
LPASIODRVSTRUCT pdl;
|
||||
LONG cr;
|
||||
DWORD index = 0;
|
||||
BOOL fin = FALSE;
|
||||
|
||||
numdrv = 0;
|
||||
lpdrvlist = 0;
|
||||
|
||||
cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum);
|
||||
while (cr == ERROR_SUCCESS) {
|
||||
if ((cr = RegEnumKey(hkEnum,index++,(LPTSTR)keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) {
|
||||
lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist);
|
||||
}
|
||||
else fin = TRUE;
|
||||
}
|
||||
if (hkEnum) RegCloseKey(hkEnum);
|
||||
|
||||
pdl = lpdrvlist;
|
||||
while (pdl) {
|
||||
numdrv++;
|
||||
pdl = pdl->next;
|
||||
}
|
||||
|
||||
if (numdrv) CoInitialize(0); // initialize COM
|
||||
}
|
||||
|
||||
|
||||
bool AsioDriverList::close()
|
||||
{
|
||||
if (numdrv) {
|
||||
deleteDrvStruct(lpdrvlist);
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LONG AsioDriverList::asioGetNumDev (VOID)
|
||||
{
|
||||
return (LONG)numdrv;
|
||||
}
|
||||
|
||||
|
||||
LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv)
|
||||
{
|
||||
LPASIODRVSTRUCT lpdrv = 0;
|
||||
long rc;
|
||||
|
||||
if (!asiodrv) return DRVERR_INVALID_PARAM;
|
||||
|
||||
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||||
if (!lpdrv->asiodrv) {
|
||||
rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv);
|
||||
if (rc == S_OK) {
|
||||
lpdrv->asiodrv = *asiodrv;
|
||||
return 0;
|
||||
}
|
||||
// else if (rc == REGDB_E_CLASSNOTREG)
|
||||
// strcpy (info->messageText, "Driver not registered in the Registration Database!");
|
||||
}
|
||||
else rc = DRVERR_DEVICE_ALREADY_OPEN;
|
||||
}
|
||||
else rc = DRVERR_DEVICE_NOT_FOUND;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
LONG AsioDriverList::asioCloseDriver (int drvID)
|
||||
{
|
||||
LPASIODRVSTRUCT lpdrv = 0;
|
||||
IASIO *iasio;
|
||||
|
||||
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||||
if (lpdrv->asiodrv) {
|
||||
iasio = (IASIO *)lpdrv->asiodrv;
|
||||
iasio->Release();
|
||||
lpdrv->asiodrv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize)
|
||||
{
|
||||
LPASIODRVSTRUCT lpdrv = 0;
|
||||
|
||||
if (!drvname) return DRVERR_INVALID_PARAM;
|
||||
|
||||
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||||
if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) {
|
||||
strcpy(drvname,lpdrv->drvname);
|
||||
}
|
||||
else {
|
||||
FMOD_memcpy(drvname,lpdrv->drvname,drvnamesize-4);
|
||||
drvname[drvnamesize-4] = '.';
|
||||
drvname[drvnamesize-3] = '.';
|
||||
drvname[drvnamesize-2] = '.';
|
||||
drvname[drvnamesize-1] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return DRVERR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize)
|
||||
{
|
||||
LPASIODRVSTRUCT lpdrv = 0;
|
||||
|
||||
if (!dllpath) return DRVERR_INVALID_PARAM;
|
||||
|
||||
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||||
if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) {
|
||||
strcpy(dllpath,lpdrv->dllpath);
|
||||
return 0;
|
||||
}
|
||||
dllpath[0] = 0;
|
||||
return DRVERR_INVALID_PARAM;
|
||||
}
|
||||
return DRVERR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid)
|
||||
{
|
||||
LPASIODRVSTRUCT lpdrv = 0;
|
||||
|
||||
if (!clsid) return DRVERR_INVALID_PARAM;
|
||||
|
||||
if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) {
|
||||
FMOD_memcpy(clsid,&lpdrv->clsid,sizeof(CLSID));
|
||||
return 0;
|
||||
}
|
||||
return DRVERR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
46
fmod/win32/src/asio/asiolist.h
Executable file
46
fmod/win32/src/asio/asiolist.h
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef __asiolist__
|
||||
#define __asiolist__
|
||||
|
||||
#define DRVERR -5000
|
||||
#define DRVERR_INVALID_PARAM DRVERR-1
|
||||
#define DRVERR_DEVICE_ALREADY_OPEN DRVERR-2
|
||||
#define DRVERR_DEVICE_NOT_FOUND DRVERR-3
|
||||
|
||||
#define MAXPATHLEN 512
|
||||
#define MAXDRVNAMELEN 128
|
||||
|
||||
struct asiodrvstruct
|
||||
{
|
||||
int drvID;
|
||||
CLSID clsid;
|
||||
char dllpath[MAXPATHLEN];
|
||||
char drvname[MAXDRVNAMELEN];
|
||||
LPVOID asiodrv;
|
||||
struct asiodrvstruct *next;
|
||||
};
|
||||
|
||||
typedef struct asiodrvstruct ASIODRVSTRUCT;
|
||||
typedef ASIODRVSTRUCT *LPASIODRVSTRUCT;
|
||||
|
||||
class AsioDriverList {
|
||||
public:
|
||||
AsioDriverList();
|
||||
bool close();
|
||||
|
||||
LONG asioOpenDriver (int,VOID **);
|
||||
LONG asioCloseDriver (int);
|
||||
|
||||
// nice to have
|
||||
LONG asioGetNumDev (VOID);
|
||||
LONG asioGetDriverName (int,char *,int);
|
||||
LONG asioGetDriverPath (int,char *,int);
|
||||
LONG asioGetDriverCLSID (int,CLSID *);
|
||||
|
||||
// or use directly access
|
||||
LPASIODRVSTRUCT lpdrvlist;
|
||||
int numdrv;
|
||||
};
|
||||
|
||||
typedef class AsioDriverList *LPASIODRIVERLIST;
|
||||
|
||||
#endif
|
||||
82
fmod/win32/src/asio/asiosys.h
Executable file
82
fmod/win32/src/asio/asiosys.h
Executable file
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef __asiosys__
|
||||
#define __asiosys__
|
||||
|
||||
#ifdef WIN32
|
||||
#undef MAC
|
||||
#define PPC 0
|
||||
#define WINDOWS 1
|
||||
#define SGI 0
|
||||
#define SUN 0
|
||||
#define LINUX 0
|
||||
#define BEOS 0
|
||||
|
||||
#define NATIVE_INT64 0
|
||||
#define IEEE754_64FLOAT 1
|
||||
|
||||
#elif BEOS
|
||||
#define MAC 0
|
||||
#define PPC 0
|
||||
#define WINDOWS 0
|
||||
#define PC 0
|
||||
#define SGI 0
|
||||
#define SUN 0
|
||||
#define LINUX 0
|
||||
|
||||
#define NATIVE_INT64 0
|
||||
#define IEEE754_64FLOAT 1
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
void DEBUGGERMESSAGE(char *string);
|
||||
#else
|
||||
#define DEBUGGERMESSAGE(a)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif SGI
|
||||
#define MAC 0
|
||||
#define PPC 0
|
||||
#define WINDOWS 0
|
||||
#define PC 0
|
||||
#define SUN 0
|
||||
#define LINUX 0
|
||||
#define BEOS 0
|
||||
|
||||
#define NATIVE_INT64 0
|
||||
#define IEEE754_64FLOAT 1
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
void DEBUGGERMESSAGE(char *string);
|
||||
#else
|
||||
#define DEBUGGERMESSAGE(a)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else // MAC
|
||||
|
||||
#define MAC 1
|
||||
#define PPC 1
|
||||
#define WINDOWS 0
|
||||
#define PC 0
|
||||
#define SGI 0
|
||||
#define SUN 0
|
||||
#define LINUX 0
|
||||
#define BEOS 0
|
||||
|
||||
#define NATIVE_INT64 0
|
||||
#define IEEE754_64FLOAT 1
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
void DEBUGGERMESSAGE(char *string);
|
||||
#else
|
||||
#define DEBUGGERMESSAGE(a)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
38
fmod/win32/src/asio/ginclude.h
Executable file
38
fmod/win32/src/asio/ginclude.h
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __gInclude__
|
||||
#define __gInclude__
|
||||
|
||||
#if SGI
|
||||
#undef BEOS
|
||||
#undef MAC
|
||||
#undef WINDOWS
|
||||
//
|
||||
#define ASIO_BIG_ENDIAN 1
|
||||
#define ASIO_CPU_MIPS 1
|
||||
#elif defined WIN32
|
||||
#undef BEOS
|
||||
#undef MAC
|
||||
#undef SGI
|
||||
#define WINDOWS 1
|
||||
#define ASIO_LITTLE_ENDIAN 1
|
||||
#define ASIO_CPU_X86 1
|
||||
#elif BEOS
|
||||
#undef MAC
|
||||
#undef SGI
|
||||
#undef WINDOWS
|
||||
#define ASIO_LITTLE_ENDIAN 1
|
||||
#define ASIO_CPU_X86 1
|
||||
//
|
||||
#else
|
||||
#define MAC 1
|
||||
#undef BEOS
|
||||
#undef WINDOWS
|
||||
#undef SGI
|
||||
#define ASIO_BIG_ENDIAN 1
|
||||
#define ASIO_CPU_PPC 1
|
||||
#endif
|
||||
|
||||
// always
|
||||
#define NATIVE_INT64 0
|
||||
#define IEEE754_64FLOAT 1
|
||||
|
||||
#endif // __gInclude__
|
||||
37
fmod/win32/src/asio/iasiodrv.h
Executable file
37
fmod/win32/src/asio/iasiodrv.h
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#include "asiosys.h"
|
||||
#include "asio.h"
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __ASIODRIVER_FWD_DEFINED__
|
||||
#define __ASIODRIVER_FWD_DEFINED__
|
||||
typedef interface IASIO IASIO;
|
||||
#endif /* __ASIODRIVER_FWD_DEFINED__ */
|
||||
|
||||
interface IASIO : public IUnknown
|
||||
{
|
||||
|
||||
virtual ASIOBool init(void *sysHandle) = 0;
|
||||
virtual void getDriverName(char *name) = 0;
|
||||
virtual long getDriverVersion() = 0;
|
||||
virtual void getErrorMessage(char *string) = 0;
|
||||
virtual ASIOError start() = 0;
|
||||
virtual ASIOError stop() = 0;
|
||||
virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;
|
||||
virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;
|
||||
virtual ASIOError getBufferSize(long *minSize, long *maxSize,
|
||||
long *preferredSize, long *granularity) = 0;
|
||||
virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;
|
||||
virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;
|
||||
virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;
|
||||
virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;
|
||||
virtual ASIOError setClockSource(long reference) = 0;
|
||||
virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
|
||||
virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;
|
||||
virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,
|
||||
long bufferSize, ASIOCallbacks *callbacks) = 0;
|
||||
virtual ASIOError disposeBuffers() = 0;
|
||||
virtual ASIOError controlPanel() = 0;
|
||||
virtual ASIOError future(long selector,void *opt) = 0;
|
||||
virtual ASIOError outputReady() = 0;
|
||||
};
|
||||
59
fmod/win32/src/c32.mac
Executable file
59
fmod/win32/src/c32.mac
Executable file
|
|
@ -0,0 +1,59 @@
|
|||
; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*-
|
||||
|
||||
|
||||
|
||||
%imacro proc 1 ; begin a procedure definition
|
||||
|
||||
%push proc
|
||||
|
||||
%ifdef PLATFORM_LINUX
|
||||
global _%1:function
|
||||
global %1:function
|
||||
%else
|
||||
global _%1
|
||||
global %1
|
||||
%endif
|
||||
|
||||
_%1:
|
||||
%1: push ebp
|
||||
|
||||
mov ebp,esp
|
||||
|
||||
%assign %$arg 8
|
||||
|
||||
%define %$procname %1
|
||||
|
||||
%endmacro
|
||||
|
||||
|
||||
|
||||
%imacro arg 0-1 4 ; used with the argument name as a label
|
||||
|
||||
%00 equ %$arg
|
||||
|
||||
%assign %$arg %1+%$arg
|
||||
|
||||
%endmacro
|
||||
|
||||
|
||||
|
||||
%imacro endproc 0
|
||||
|
||||
%ifnctx proc
|
||||
|
||||
%error Mismatched `endproc'/`proc'
|
||||
|
||||
%else
|
||||
|
||||
leave
|
||||
|
||||
ret
|
||||
|
||||
__end_%$procname: ; useful for calculating function size
|
||||
___end_%$procname:
|
||||
|
||||
%pop
|
||||
|
||||
%endif
|
||||
|
||||
%endmacro
|
||||
211
fmod/win32/src/fmod_3dl2.h
Executable file
211
fmod/win32/src/fmod_3dl2.h
Executable file
|
|
@ -0,0 +1,211 @@
|
|||
// 3DL2.H
|
||||
//
|
||||
|
||||
#ifndef _3DL2_H_INCLUDED
|
||||
#define _3DL2_H_INCLUDED
|
||||
|
||||
#include <dxsdkver.h>
|
||||
#if (_DXSDK_PRODUCT_MAJOR < 9 || (_DXSDK_PRODUCT_MAJOR == 9 && _DXSDK_PRODUCT_MINOR < 21))
|
||||
#include <dplay.h> /* This defines DWORD_PTR for dsound.h to use. */
|
||||
#endif
|
||||
#include <dsound.h>
|
||||
|
||||
#define FLOAT float
|
||||
#define LONG long
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
// I3DL2 listener property set {DA0F0520-300A-11D3-8A2B-0060970DB011}
|
||||
DEFINE_GUID(DSPROPSETID_I3DL2_ListenerProperties,
|
||||
0xDA0F0520,
|
||||
0x300A,
|
||||
0x11D3,
|
||||
0x8A, 0x2B, 0x00, 0x60, 0x97, 0x0D, 0xB0, 0x11);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_I3DL2LISTENER_ALL, // sets all I3DL2 listener properties
|
||||
DSPROPERTY_I3DL2LISTENER_ROOM, // room effect level at low frequencies
|
||||
DSPROPERTY_I3DL2LISTENER_ROOMHF, // room effect high-frequency level re. low frequency level
|
||||
DSPROPERTY_I3DL2LISTENER_ROOMROLLOFFFACTOR, // like DS3D flRolloffFactor but for room effect
|
||||
DSPROPERTY_I3DL2LISTENER_DECAYTIME, // reverberation decay time at low-frequencies
|
||||
DSPROPERTY_I3DL2LISTENER_DECAYHFRATIO, // high-frequency to low-frequency decay time ratio
|
||||
DSPROPERTY_I3DL2LISTENER_REFLECTIONS, // early reflections level relative to room effect
|
||||
DSPROPERTY_I3DL2LISTENER_REFLECTIONSDELAY, // delay time of first reflection
|
||||
DSPROPERTY_I3DL2LISTENER_REVERB, // late reverberation level relative to room effect
|
||||
DSPROPERTY_I3DL2LISTENER_REVERBDELAY, // late reverberation delay time relative to first reflection
|
||||
DSPROPERTY_I3DL2LISTENER_DIFFUSION, // reverberation diffusion (echo density)
|
||||
DSPROPERTY_I3DL2LISTENER_DENSITY, // reverberation density (modal density)
|
||||
DSPROPERTY_I3DL2LISTENER_HFREFERENCE // reference high frequency
|
||||
} DSPROPERTY_I3DL2_LISTENERPROPERTY;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2LISTENER_ALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
// - all times are in seconds (s)
|
||||
typedef struct _I3DL2_LISTENERPROPERTIES
|
||||
{
|
||||
LONG lRoom; // [-10000, 0] default: -10000 mB
|
||||
LONG lRoomHF; // [-10000, 0] default: 0 mB
|
||||
FLOAT flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
|
||||
FLOAT flDecayTime; // [0.1, 20.0] default: 1.0 s
|
||||
FLOAT flDecayHFRatio; // [0.1, 2.0] default: 0.5
|
||||
LONG lReflections; // [-10000, 1000] default: -10000 mB
|
||||
FLOAT flReflectionsDelay; // [0.0, 0.3] default: 0.02 s
|
||||
LONG lReverb; // [-10000, 2000] default: -10000 mB
|
||||
FLOAT flReverbDelay; // [0.0, 0.1] default: 0.04 s
|
||||
FLOAT flDiffusion ; // [0.0, 100.0] default: 100.0 %
|
||||
FLOAT flDensity; // [0.0, 100.0] default: 100.0 %
|
||||
FLOAT flHFReference; // [20.0, 20000.0] default: 5000.0 Hz
|
||||
} I3DL2_LISTENERPROPERTIES, *LPI3DL2_LISTENERPROPERTIES;
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define I3DL2LISTENER_MINROOM -10000
|
||||
#define I3DL2LISTENER_MAXROOM 0
|
||||
#define I3DL2LISTENER_DEFAULTROOM -10000
|
||||
|
||||
#define I3DL2LISTENER_MINROOMHF -10000
|
||||
#define I3DL2LISTENER_MAXROOMHF 0
|
||||
#define I3DL2LISTENER_DEFAULTROOMHF 0
|
||||
|
||||
#define I3DL2LISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define I3DL2LISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define I3DL2LISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDECAYTIME 0.1f
|
||||
#define I3DL2LISTENER_MAXDECAYTIME 20.0f
|
||||
#define I3DL2LISTENER_DEFAULTDECAYTIME 1.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define I3DL2LISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define I3DL2LISTENER_DEFAULTDECAYHFRATIO 0.5f
|
||||
|
||||
#define I3DL2LISTENER_MINREFLECTIONS -10000
|
||||
#define I3DL2LISTENER_MAXREFLECTIONS 1000
|
||||
#define I3DL2LISTENER_DEFAULTREFLECTIONS -10000
|
||||
|
||||
#define I3DL2LISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define I3DL2LISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define I3DL2LISTENER_DEFAULTREFLECTIONSDELAY 0.02f
|
||||
|
||||
#define I3DL2LISTENER_MINREVERB -10000
|
||||
#define I3DL2LISTENER_MAXREVERB 2000
|
||||
#define I3DL2LISTENER_DEFAULTREVERB -10000
|
||||
|
||||
#define I3DL2LISTENER_MINREVERBDELAY 0.0f
|
||||
#define I3DL2LISTENER_MAXREVERBDELAY 0.1f
|
||||
#define I3DL2LISTENER_DEFAULTREVERBDELAY 0.04f
|
||||
|
||||
#define I3DL2LISTENER_MINDIFFUSION 0.0f
|
||||
#define I3DL2LISTENER_MAXDIFFUSION 100.0f
|
||||
#define I3DL2LISTENER_DEFAULTDIFFUSION 100.0f
|
||||
|
||||
#define I3DL2LISTENER_MINDENSITY 0.0f
|
||||
#define I3DL2LISTENER_MAXDENSITY 100.0f
|
||||
#define I3DL2LISTENER_DEFAULTDENSITY 100.0f
|
||||
|
||||
#define I3DL2LISTENER_MINHFREFERENCE 20.0f
|
||||
#define I3DL2LISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define I3DL2LISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
// I3DL2 buffer property set {DA0F0521-300A-11D3-8A2B-0060970DB011}
|
||||
DEFINE_GUID(DSPROPSETID_I3DL2_BufferProperties,
|
||||
0xDA0F0521,
|
||||
0x300A,
|
||||
0x11D3,
|
||||
0x8A, 0x2B, 0x00, 0x60, 0x97, 0x0D, 0xB0, 0x11);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_I3DL2BUFFER_ALL, // sets all I3DL2 buffer properties
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONALL, // sets both obstruction properties
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSIONALL, // sets both occlusion properties
|
||||
DSPROPERTY_I3DL2BUFFER_DIRECT, // additional direct path level correction
|
||||
DSPROPERTY_I3DL2BUFFER_DIRECTHF, // additional direct path high-frequency re. low-frequency level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOM, // additional room effect level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOMHF, // additional room effect high-frequency re. low-frequency level correction
|
||||
DSPROPERTY_I3DL2BUFFER_ROOMROLLOFFFACTOR, // like DS3D flRolloffFactor but for room effect
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTION, // main obstruction control (attenuation at high frequencies)
|
||||
DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONLFRATIO, // obstruction low-frequency re. high-frequency ratio
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSION, // main occlusion control (attenuation at high frequencies)
|
||||
DSPROPERTY_I3DL2BUFFER_OCCLUSIONLFRATIO // occlusion low-frequency re. high-frequency ratio
|
||||
} DSPROPERTY_I3DL2_BUFFERPROPERTY;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_OBSTRUCTIONALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_OBSTRUCTIONPROPERTIES
|
||||
{
|
||||
LONG lHFLevel; // [-10000, 0] default: 0 mB
|
||||
FLOAT flLFRatio; // [0.0, 1.0] default: 0.0
|
||||
} I3DL2_OBSTRUCTIONPROPERTIES, *LPI3DL2_OBSTRUCTIONPROPERTIES;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_OCCLUSIONALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_OCCLUSIONPROPERTIES
|
||||
{
|
||||
LONG lHFLevel; // [-10000, 0] default: 0 mB
|
||||
FLOAT flLFRatio; // [0.0, 1.0] default: 0.25
|
||||
} I3DL2_OCCLUSIONPROPERTIES, *LPI3DL2_OCCLUSIONPROPERTIES;
|
||||
|
||||
// use this structure for DSPROPERTY_I3DL2BUFFER_ALL
|
||||
// - all levels are hundredths of decibels (mB)
|
||||
typedef struct _I3DL2_BUFFERPROPERTIES
|
||||
{
|
||||
LONG lDirect; // [-10000, 1000] default: 0 mB
|
||||
LONG lDirectHF; // [-10000, 0] default: 0 mB
|
||||
LONG lRoom; // [-10000, 1000] default: 0 mB
|
||||
LONG lRoomHF; // [-10000, 0] default: 0 mB
|
||||
FLOAT flRoomRolloffFactor; // [0.0, 10.0] default: 0.0
|
||||
I3DL2_OBSTRUCTIONPROPERTIES Obstruction;
|
||||
I3DL2_OCCLUSIONPROPERTIES Occlusion;
|
||||
} I3DL2_BUFFERPROPERTIES, *LPI3DL2_BUFFERPROPERTIES;
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define I3DL2BUFFER_MINDIRECT -10000
|
||||
#define I3DL2BUFFER_MAXDIRECT 1000
|
||||
#define I3DL2BUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define I3DL2BUFFER_MINDIRECTHF -10000
|
||||
#define I3DL2BUFFER_MAXDIRECTHF 0
|
||||
#define I3DL2BUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOM -10000
|
||||
#define I3DL2BUFFER_MAXROOM 1000
|
||||
#define I3DL2BUFFER_DEFAULTROOM 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOMHF -10000
|
||||
#define I3DL2BUFFER_MAXROOMHF 0
|
||||
#define I3DL2BUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define I3DL2BUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define I3DL2BUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define I3DL2BUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define I3DL2BUFFER_MINOBSTRUCTION -10000
|
||||
#define I3DL2BUFFER_MAXOBSTRUCTION 0
|
||||
#define I3DL2BUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define I3DL2BUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define I3DL2BUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define I3DL2BUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define I3DL2BUFFER_MINOCCLUSION -10000
|
||||
#define I3DL2BUFFER_MAXOCCLUSION 0
|
||||
#define I3DL2BUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define I3DL2BUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define I3DL2BUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define I3DL2BUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
1280
fmod/win32/src/fmod_channel_dsound.cpp
Executable file
1280
fmod/win32/src/fmod_channel_dsound.cpp
Executable file
File diff suppressed because it is too large
Load diff
67
fmod/win32/src/fmod_channel_dsound.h
Executable file
67
fmod/win32/src/fmod_channel_dsound.h
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef _FMOD_CHANNEL_DSOUND_H
|
||||
#define _FMOD_CHANNEL_DSOUND_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_DSOUND
|
||||
|
||||
#include "fmod_channel_real.h"
|
||||
|
||||
#ifdef PLATFORM_32BIT
|
||||
typedef unsigned long DWORD;
|
||||
typedef DWORD DWORD_PTR;
|
||||
#endif
|
||||
|
||||
#include <dsound.h>
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class Output;
|
||||
|
||||
class ChannelDSound : public ChannelReal
|
||||
{
|
||||
friend class OutputDSound;
|
||||
|
||||
private:
|
||||
|
||||
bool mLOCSoftware;
|
||||
|
||||
protected:
|
||||
|
||||
OutputDSound *mOutputDSound;
|
||||
IDirectSoundBuffer8 *mBuffer;
|
||||
IDirectSound3DBuffer *mBuffer3D;
|
||||
IKsPropertySet *mBufferReverb;
|
||||
IKsPropertySet *mBufferQuality;
|
||||
|
||||
public:
|
||||
|
||||
ChannelDSound() {}
|
||||
|
||||
FMOD_RESULT init (int index, SystemI *system, Output *output, DSPI *dspmixtarget);
|
||||
FMOD_RESULT alloc ();
|
||||
FMOD_RESULT start ();
|
||||
|
||||
FMOD_RESULT stop ();
|
||||
FMOD_RESULT setVolume (float volume);
|
||||
FMOD_RESULT setFrequency (float frequency);
|
||||
FMOD_RESULT setPan (float pan, float fbpan = 1);
|
||||
FMOD_RESULT setSpeakerLevels (int speaker, float *levels, int numlevels);
|
||||
FMOD_RESULT setSpeakerMix (float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright);
|
||||
FMOD_RESULT setPaused (bool paused);
|
||||
FMOD_RESULT setPosition (unsigned int position, FMOD_TIMEUNIT postype);
|
||||
FMOD_RESULT getPosition (unsigned int *position, FMOD_TIMEUNIT postype);
|
||||
FMOD_RESULT set3DAttributes ();
|
||||
FMOD_RESULT set3DMinMaxDistance ();
|
||||
FMOD_RESULT set3DOcclusion (float directOcclusion, float reverbOcclusion);
|
||||
|
||||
FMOD_RESULT isPlaying (bool *isplaying, bool includethreadlatency = false);
|
||||
FMOD_RESULT setMode (FMOD_MODE mode);
|
||||
|
||||
FMOD_RESULT getBuffer3D (IDirectSound3DBuffer **buffer3d);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_DSOUND */
|
||||
|
||||
#endif
|
||||
193
fmod/win32/src/fmod_channel_dsound_eax2.cpp
Executable file
193
fmod/win32/src/fmod_channel_dsound_eax2.cpp
Executable file
|
|
@ -0,0 +1,193 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_channel_dsound_eax2.h"
|
||||
#include "fmod_eax2.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX2::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXBUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
NOW SET CHANNEL PROPERTIES
|
||||
*/
|
||||
dsprops.lDirect = prop->Direct;
|
||||
dsprops.lDirectHF = prop->DirectHF;
|
||||
dsprops.lRoom = prop->Room;
|
||||
dsprops.lRoomHF = prop->RoomHF;
|
||||
dsprops.lObstruction = prop->Obstruction;
|
||||
dsprops.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
dsprops.lOcclusion = prop->Occlusion;
|
||||
dsprops.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
dsprops.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
dsprops.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
dsprops.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprops.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
dsprops.dwFlags = prop->Flags;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, NULL, 0, &dsprops, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX2::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXBUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get reverb properties
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, NULL, 0, &dsprops, sizeof(EAXBUFFERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Direct = dsprops.lDirect;
|
||||
prop->DirectHF = dsprops.lDirectHF;
|
||||
prop->Room = dsprops.lRoom;
|
||||
prop->RoomHF = dsprops.lRoomHF;
|
||||
prop->Obstruction = dsprops.lObstruction;
|
||||
prop->ObstructionLFRatio = dsprops.flObstructionLFRatio;
|
||||
prop->Occlusion = dsprops.lOcclusion;
|
||||
prop->OcclusionLFRatio = dsprops.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = dsprops.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = 0;
|
||||
prop->Exclusion = 0;
|
||||
prop->ExclusionLFRatio = 0;
|
||||
prop->OutsideVolumeHF = dsprops.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = 0;
|
||||
prop->RolloffFactor = 0;
|
||||
prop->RoomRolloffFactor = dsprops.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = dsprops.flAirAbsorptionFactor;
|
||||
prop->Flags = dsprops.dwFlags;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
fmod/win32/src/fmod_channel_dsound_eax2.h
Executable file
25
fmod/win32/src/fmod_channel_dsound_eax2.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _FMOD_CHANNEL_DSOUND_EAX2_H
|
||||
#define _FMOD_CHANNEL_DSOUND_EAX2_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_dsound.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelDSoundEAX2 : public ChannelDSound
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelDSoundEAX2() {};
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
|
||||
#endif
|
||||
197
fmod/win32/src/fmod_channel_dsound_eax3.cpp
Executable file
197
fmod/win32/src/fmod_channel_dsound_eax3.cpp
Executable file
|
|
@ -0,0 +1,197 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_dsound_eax3.h"
|
||||
#include "fmod_eax3.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX3::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXBUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
NOW SET CHANNEL PROPERTIES
|
||||
*/
|
||||
dsprops.lDirect = prop->Direct;
|
||||
dsprops.lDirectHF = prop->DirectHF;
|
||||
dsprops.lRoom = prop->Room;
|
||||
dsprops.lRoomHF = prop->RoomHF;
|
||||
dsprops.lObstruction = prop->Obstruction;
|
||||
dsprops.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
dsprops.lOcclusion = prop->Occlusion;
|
||||
dsprops.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
dsprops.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
dsprops.flOcclusionDirectRatio = prop->OcclusionDirectRatio;
|
||||
dsprops.lExclusion = prop->Exclusion;
|
||||
dsprops.flExclusionLFRatio = prop->ExclusionLFRatio;
|
||||
dsprops.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
dsprops.flDopplerFactor = prop->DopplerFactor;
|
||||
dsprops.flRolloffFactor = prop->RolloffFactor;
|
||||
dsprops.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprops.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
dsprops.ulFlags = prop->Flags;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, NULL, 0, &dsprops, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX3::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXBUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Get reverb properties
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, NULL, 0, &dsprops, sizeof(EAXBUFFERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Direct = dsprops.lDirect;
|
||||
prop->DirectHF = dsprops.lDirectHF;
|
||||
prop->Room = dsprops.lRoom;
|
||||
prop->RoomHF = dsprops.lRoomHF;
|
||||
prop->Obstruction = dsprops.lObstruction;
|
||||
prop->ObstructionLFRatio = dsprops.flObstructionLFRatio;
|
||||
prop->Occlusion = dsprops.lOcclusion;
|
||||
prop->OcclusionLFRatio = dsprops.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = dsprops.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = dsprops.flOcclusionDirectRatio;
|
||||
prop->Exclusion = dsprops.lExclusion;
|
||||
prop->ExclusionLFRatio = dsprops.flExclusionLFRatio;
|
||||
prop->OutsideVolumeHF = dsprops.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = dsprops.flDopplerFactor;
|
||||
prop->RolloffFactor = dsprops.flRolloffFactor;
|
||||
prop->RoomRolloffFactor = dsprops.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = dsprops.flAirAbsorptionFactor;
|
||||
prop->Flags = dsprops.ulFlags;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
fmod/win32/src/fmod_channel_dsound_eax3.h
Executable file
25
fmod/win32/src/fmod_channel_dsound_eax3.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _FMOD_CHANNEL_DSOUND_EAX3_H
|
||||
#define _FMOD_CHANNEL_DSOUND_EAX3_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_dsound.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelDSoundEAX3 : public ChannelDSound
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelDSoundEAX3() {}
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
|
||||
#endif
|
||||
314
fmod/win32/src/fmod_channel_dsound_eax4.cpp
Executable file
314
fmod/win32/src/fmod_channel_dsound_eax4.cpp
Executable file
|
|
@ -0,0 +1,314 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_dsound_eax4.h"
|
||||
#include "fmod_eax4.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_soundi.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX4::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXSOURCEPROPERTIES eaxsrcprops;
|
||||
EAXACTIVEFXSLOTS eaxslots;
|
||||
GUID guid;
|
||||
unsigned int flags = prop->Flags;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set the target FX slot(s) for this source
|
||||
*/
|
||||
if ((flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0) &&
|
||||
(flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1) &&
|
||||
(flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
Set ACTIVE FX slot(s)
|
||||
*/
|
||||
if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[0], &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE0);
|
||||
|
||||
if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE1);
|
||||
}
|
||||
else if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE2);
|
||||
}
|
||||
}
|
||||
else if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[0], &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE1);
|
||||
|
||||
if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE2);
|
||||
}
|
||||
}
|
||||
else if (flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[0], &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
flags = (flags & ~FMOD_REVERB_CHANNELFLAGS_INSTANCE2);
|
||||
}
|
||||
else // Set to Slot 0 by default
|
||||
{
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[0], &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxslots.guidActiveFXSlots[1], &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, EAXSOURCE_ACTIVEFXSLOTID, NULL, 0, &eaxslots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
/*
|
||||
NOW SET CHANNEL PROPERTIES
|
||||
*/
|
||||
eaxsrcprops.lDirect = prop->Direct;
|
||||
eaxsrcprops.lDirectHF = prop->DirectHF;
|
||||
eaxsrcprops.lRoom = prop->Room;
|
||||
eaxsrcprops.lRoomHF = prop->RoomHF;
|
||||
eaxsrcprops.lObstruction = prop->Obstruction;
|
||||
eaxsrcprops.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
eaxsrcprops.lOcclusion = prop->Occlusion;
|
||||
eaxsrcprops.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
eaxsrcprops.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
eaxsrcprops.flOcclusionDirectRatio = prop->OcclusionDirectRatio;
|
||||
eaxsrcprops.lExclusion = prop->Exclusion;
|
||||
eaxsrcprops.flExclusionLFRatio = prop->ExclusionLFRatio;
|
||||
eaxsrcprops.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
eaxsrcprops.flDopplerFactor = prop->DopplerFactor;
|
||||
eaxsrcprops.flRolloffFactor = prop->RolloffFactor;
|
||||
eaxsrcprops.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxsrcprops.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
eaxsrcprops.ulFlags = flags;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, EAXSOURCE_ALLPARAMETERS, NULL, 0, &eaxsrcprops, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundEAX4::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXSOURCEPROPERTIES eaxsrcprops;
|
||||
EAXACTIVEFXSLOTS eaxslots;
|
||||
GUID guid;
|
||||
GUID guidfx0, guidfx2, guidfx3;
|
||||
ULONG ulReceived;
|
||||
int noActiveSlots = 0;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Get reverb properties
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, EAXSOURCE_ALLPARAMETERS, NULL, 0, &eaxsrcprops, sizeof(EAXSOURCEPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Direct = eaxsrcprops.lDirect;
|
||||
prop->DirectHF = eaxsrcprops.lDirectHF;
|
||||
prop->Room = eaxsrcprops.lRoom;
|
||||
prop->RoomHF = eaxsrcprops.lRoomHF;
|
||||
prop->Obstruction = eaxsrcprops.lObstruction;
|
||||
prop->ObstructionLFRatio = eaxsrcprops.flObstructionLFRatio;
|
||||
prop->Occlusion = eaxsrcprops.lOcclusion;
|
||||
prop->OcclusionLFRatio = eaxsrcprops.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = eaxsrcprops.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = eaxsrcprops.flOcclusionDirectRatio;
|
||||
prop->Exclusion = eaxsrcprops.lExclusion;
|
||||
prop->ExclusionLFRatio = eaxsrcprops.flExclusionLFRatio;
|
||||
prop->OutsideVolumeHF = eaxsrcprops.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = eaxsrcprops.flDopplerFactor;
|
||||
prop->RolloffFactor = eaxsrcprops.flRolloffFactor;
|
||||
prop->RoomRolloffFactor = eaxsrcprops.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = eaxsrcprops.flAirAbsorptionFactor;
|
||||
prop->Flags = eaxsrcprops.ulFlags;
|
||||
|
||||
hr = mBufferReverb->Get(guid, EAXSOURCE_ACTIVEFXSLOTID, NULL, 0, &eaxslots, sizeof(EAXACTIVEFXSLOTS), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guidfx0, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&guidfx2, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&guidfx3, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
|
||||
if (!memcmp(&eaxslots.guidActiveFXSlots[0], &guidfx0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxslots.guidActiveFXSlots[0], &guidfx2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE1;
|
||||
}
|
||||
else if (!memcmp(&eaxslots.guidActiveFXSlots[0], &guidfx3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else
|
||||
{
|
||||
noActiveSlots++;
|
||||
}
|
||||
|
||||
if (!memcmp(&eaxslots.guidActiveFXSlots[1], &guidfx0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxslots.guidActiveFXSlots[1], &guidfx2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE1;
|
||||
}
|
||||
else if (!memcmp(&eaxslots.guidActiveFXSlots[1], &guidfx3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else
|
||||
{
|
||||
noActiveSlots++;
|
||||
}
|
||||
|
||||
if (noActiveSlots == 2) // If no slots have been assigned, assign to slot 0
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
fmod/win32/src/fmod_channel_dsound_eax4.h
Executable file
25
fmod/win32/src/fmod_channel_dsound_eax4.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _FMOD_CHANNEL_DSOUND_EAX4_H
|
||||
#define _FMOD_CHANNEL_DSOUND_EAX4_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_dsound.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelDSoundEAX4 : public ChannelDSound
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelDSoundEAX4() { };
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
|
||||
#endif
|
||||
188
fmod/win32/src/fmod_channel_dsound_i3dl2.cpp
Executable file
188
fmod/win32/src/fmod_channel_dsound_i3dl2.cpp
Executable file
|
|
@ -0,0 +1,188 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_I3DL2
|
||||
|
||||
#include "fmod_3dl2.h"
|
||||
#include "fmod_channel_dsound_i3dl2.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundI3DL2::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
I3DL2_BUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
NOW SET CHANNEL PROPERTIES
|
||||
*/
|
||||
dsprops.lDirect = prop->Direct;
|
||||
dsprops.lDirectHF = prop->DirectHF;
|
||||
dsprops.lRoom = prop->Room;
|
||||
dsprops.lRoomHF = prop->RoomHF;
|
||||
dsprops.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprops.Obstruction.flLFRatio = prop->ObstructionLFRatio;
|
||||
dsprops.Obstruction.lHFLevel = prop->Obstruction;
|
||||
dsprops.Occlusion.flLFRatio = prop->OcclusionLFRatio;
|
||||
dsprops.Occlusion.lHFLevel = prop->Occlusion;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_I3DL2BUFFER_ALL, NULL, 0, &dsprops, sizeof(I3DL2_BUFFERPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelDSoundI3DL2::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
I3DL2_BUFFERPROPERTIES dsprops;
|
||||
GUID guid;
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!mOutputDSound)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mBuffer3D)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN REVERB INTERFACE
|
||||
*/
|
||||
if (!mBufferReverb)
|
||||
{
|
||||
if (mFlags & CHANNELREAL_FLAG_PAUSED && mOutputDSound->mDirectXVersion >= 8)
|
||||
{
|
||||
mBuffer->AcquireResources(DSBPLAY_LOCHARDWARE, 0, NULL);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
hr = mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Get reverb properties
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_BufferProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_I3DL2BUFFER_ALL, NULL, 0, &dsprops, sizeof(I3DL2_BUFFERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Direct = dsprops.lDirect;
|
||||
prop->DirectHF = dsprops.lDirectHF;
|
||||
prop->Room = dsprops.lRoom;
|
||||
prop->RoomHF = dsprops.lRoomHF;
|
||||
prop->Obstruction = dsprops.Obstruction.lHFLevel;
|
||||
prop->ObstructionLFRatio = dsprops.Obstruction.flLFRatio;
|
||||
prop->Occlusion = dsprops.Occlusion.lHFLevel;
|
||||
prop->OcclusionLFRatio = dsprops.Occlusion.flLFRatio;
|
||||
prop->OcclusionRoomRatio = 0;
|
||||
prop->OcclusionDirectRatio = 0;
|
||||
prop->Exclusion = 0;
|
||||
prop->ExclusionLFRatio = 0;
|
||||
prop->OutsideVolumeHF = 0;
|
||||
prop->DopplerFactor = 0;
|
||||
prop->RolloffFactor = 0;
|
||||
prop->RoomRolloffFactor = dsprops.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = 0;
|
||||
prop->Flags = 0;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
fmod/win32/src/fmod_channel_dsound_i3dl2.h
Executable file
25
fmod/win32/src/fmod_channel_dsound_i3dl2.h
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _FMOD_CHANNEL_DSOUND_I3DL2_H
|
||||
#define _FMOD_CHANNEL_DSOUND_I3DL2_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_I3DL2
|
||||
|
||||
#include "fmod_channel_dsound.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelDSoundI3DL2 : public ChannelDSound
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelDSoundI3DL2() {};
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_I3DL2 */
|
||||
|
||||
#endif
|
||||
2441
fmod/win32/src/fmod_channel_openal.cpp
Executable file
2441
fmod/win32/src/fmod_channel_openal.cpp
Executable file
File diff suppressed because it is too large
Load diff
76
fmod/win32/src/fmod_channel_openal.h
Executable file
76
fmod/win32/src/fmod_channel_openal.h
Executable file
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef _FMOD_CHANNEL_OPENAL_H
|
||||
#define _FMOD_CHANNEL_OPENAL_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
|
||||
#include "fmod_channel_real.h"
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_dsp_wavetable.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelOpenAL : public ChannelReal
|
||||
{
|
||||
friend class OutputOpenAL;
|
||||
|
||||
protected:
|
||||
|
||||
DSPI *mDSPHead;
|
||||
DSPFilter mDSPHeadMemory;
|
||||
DSPWaveTable *mDSPWaveTable;
|
||||
DSPWaveTable mDSPWaveTableMemory;
|
||||
DSPResampler *mDSPResampler; // Connected between mDSPHead and mDSPWaveTable sometimes
|
||||
DSPI *mDSPLowPass; // Optional if the user specifies FMOD_INIT_SOFTWARE_OCCLUSION
|
||||
DSPCodec *mDSPCodec;
|
||||
DSPConnection *mDSPConnection;
|
||||
|
||||
OutputOpenAL *mOutputOAL;
|
||||
int mNumSources;
|
||||
SourceOpenAL *mSources[16];
|
||||
short *mBuffer;
|
||||
float *mTempBuffer;
|
||||
bool mInitialFill;
|
||||
unsigned int mDSPTick;
|
||||
|
||||
public:
|
||||
|
||||
ChannelOpenAL();
|
||||
|
||||
FMOD_RESULT init (int index, SystemI *system, Output *output, DSPI *dspmixtarget);
|
||||
FMOD_RESULT close ();
|
||||
FMOD_RESULT alloc ();
|
||||
FMOD_RESULT alloc (DSPI *dsp);
|
||||
FMOD_RESULT start ();
|
||||
FMOD_RESULT stop ();
|
||||
FMOD_RESULT setVolume (float volume);
|
||||
FMOD_RESULT setFrequency (float frequency);
|
||||
FMOD_RESULT setPan (float pan, float fbpan = 1);
|
||||
FMOD_RESULT setSpeakerLevels (int speaker, float *levels, int numlevels);
|
||||
FMOD_RESULT setPaused (bool paused);
|
||||
FMOD_RESULT setPosition (unsigned int position, FMOD_TIMEUNIT postype);
|
||||
FMOD_RESULT getPosition (unsigned int *position, FMOD_TIMEUNIT postype);
|
||||
FMOD_RESULT setLoopPoints (unsigned int loopstart, unsigned int looplength);
|
||||
FMOD_RESULT setLoopCount (int loopcount);
|
||||
FMOD_RESULT setMode (FMOD_MODE mode);
|
||||
FMOD_RESULT set3DAttributes ();
|
||||
FMOD_RESULT set3DMinMaxDistance ();
|
||||
FMOD_RESULT set3DOcclusion (float directOcclusion, float reverbOcclusion);
|
||||
FMOD_RESULT isPlaying (bool *isplaying, bool includethreadlatency = false);
|
||||
FMOD_RESULT getSpectrum (float *spectrumarray, int numentries, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype);
|
||||
FMOD_RESULT getWaveData (float *wavearray, int numentries, int channeloffset);
|
||||
FMOD_RESULT getDSPHead (DSPI **dsp) { *dsp = mDSPHead; return FMOD_OK; }
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT setupDSPCodec (DSPI *dsp);
|
||||
FMOD_RESULT getDSPCodec (DSPCodec **dsp) { *dsp = mDSPCodec; return FMOD_OK; }
|
||||
|
||||
virtual FMOD_RESULT setupChannel ();
|
||||
FMOD_RESULT updateChannel ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* _FMOD_CHANNEL_OPENAL_H */
|
||||
210
fmod/win32/src/fmod_channel_openal_eax2.cpp
Executable file
210
fmod/win32/src/fmod_channel_openal_eax2.cpp
Executable file
|
|
@ -0,0 +1,210 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal_eax2.h"
|
||||
#include "fmod_eax2.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Initialise this channel for EAX2 specific settings
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
This will also reset the sources back to defaults when a new channel
|
||||
is reusing sources
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX2::setupChannel()
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default channel reverb properties
|
||||
*/
|
||||
eaxBufferProperties.lDirect = EAXBUFFER_DEFAULTDIRECT;
|
||||
eaxBufferProperties.lDirectHF = EAXBUFFER_DEFAULTDIRECTHF;
|
||||
eaxBufferProperties.lRoom = EAXBUFFER_DEFAULTROOM;
|
||||
eaxBufferProperties.lRoomHF = EAXBUFFER_DEFAULTROOMHF;
|
||||
eaxBufferProperties.flRoomRolloffFactor = EAXBUFFER_DEFAULTROOMROLLOFFFACTOR;
|
||||
eaxBufferProperties.lObstruction = EAXBUFFER_DEFAULTOBSTRUCTION;
|
||||
eaxBufferProperties.flObstructionLFRatio = EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO;
|
||||
eaxBufferProperties.lOcclusion = EAXBUFFER_DEFAULTOCCLUSION;
|
||||
eaxBufferProperties.flOcclusionLFRatio = EAXBUFFER_DEFAULTOCCLUSIONLFRATIO;
|
||||
eaxBufferProperties.flOcclusionRoomRatio = EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO;
|
||||
eaxBufferProperties.lOutsideVolumeHF = EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF;
|
||||
eaxBufferProperties.flAirAbsorptionFactor = EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR;
|
||||
eaxBufferProperties.dwFlags = EAXBUFFER_DEFAULTFLAGS;
|
||||
|
||||
/*
|
||||
Apply the defaults to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[i]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set the reverb properties on the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX2::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the channel reverb properties
|
||||
*/
|
||||
eaxBufferProperties.lDirect = prop->Direct;
|
||||
eaxBufferProperties.lDirectHF = prop->DirectHF;
|
||||
eaxBufferProperties.lRoom = prop->Room;
|
||||
eaxBufferProperties.lRoomHF = prop->RoomHF;
|
||||
eaxBufferProperties.lObstruction = prop->Obstruction;
|
||||
eaxBufferProperties.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
eaxBufferProperties.lOcclusion = prop->Occlusion;
|
||||
eaxBufferProperties.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
eaxBufferProperties.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
eaxBufferProperties.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
eaxBufferProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxBufferProperties.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
eaxBufferProperties.dwFlags = prop->Flags;
|
||||
|
||||
/*
|
||||
Apply the values to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[i]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Get the reverb properties from the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX2::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Get the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[0]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
FMOD_memset(prop, 0, sizeof(FMOD_REVERB_CHANNELPROPERTIES));
|
||||
prop->Direct = eaxBufferProperties.lDirect;
|
||||
prop->DirectHF = eaxBufferProperties.lDirectHF;
|
||||
prop->Room = eaxBufferProperties.lRoom;
|
||||
prop->RoomHF = eaxBufferProperties.lRoomHF;
|
||||
prop->Obstruction = eaxBufferProperties.lObstruction;
|
||||
prop->ObstructionLFRatio = eaxBufferProperties.flObstructionLFRatio;
|
||||
prop->Occlusion = eaxBufferProperties.lOcclusion;
|
||||
prop->OcclusionLFRatio = eaxBufferProperties.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = eaxBufferProperties.flOcclusionRoomRatio;
|
||||
prop->OutsideVolumeHF = eaxBufferProperties.lOutsideVolumeHF;
|
||||
prop->RoomRolloffFactor = eaxBufferProperties.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = eaxBufferProperties.flAirAbsorptionFactor;
|
||||
prop->Flags = eaxBufferProperties.dwFlags;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
29
fmod/win32/src/fmod_channel_openal_eax2.h
Executable file
29
fmod/win32/src/fmod_channel_openal_eax2.h
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef _FMOD_CHANNEL_OPENAL_EAX2_H
|
||||
#define _FMOD_CHANNEL_OPENAL_EAX2_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelOpenALEAX2 : public ChannelOpenAL
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelOpenALEAX2() {};
|
||||
|
||||
FMOD_RESULT setupChannel ();
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* _FMOD_CHANNEL_OPENAL_EAX2_H */
|
||||
225
fmod/win32/src/fmod_channel_openal_eax3.cpp
Executable file
225
fmod/win32/src/fmod_channel_openal_eax3.cpp
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal_eax3.h"
|
||||
#include "fmod_eax3.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Initialise this channel for EAX3 specific settings
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
This will also reset the sources back to defaults when a new channel
|
||||
is reusing sources
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX3::setupChannel()
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default channel reverb properties
|
||||
*/
|
||||
eaxBufferProperties.lDirect = EAXBUFFER_DEFAULTDIRECT;
|
||||
eaxBufferProperties.lDirectHF = EAXBUFFER_DEFAULTDIRECTHF;
|
||||
eaxBufferProperties.lRoom = EAXBUFFER_DEFAULTROOM;
|
||||
eaxBufferProperties.lRoomHF = EAXBUFFER_DEFAULTROOMHF;
|
||||
eaxBufferProperties.lObstruction = EAXBUFFER_DEFAULTOBSTRUCTION;
|
||||
eaxBufferProperties.flObstructionLFRatio = EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO;
|
||||
eaxBufferProperties.lOcclusion = EAXBUFFER_DEFAULTOCCLUSION;
|
||||
eaxBufferProperties.flOcclusionLFRatio = EAXBUFFER_DEFAULTOCCLUSIONLFRATIO;
|
||||
eaxBufferProperties.flOcclusionRoomRatio = EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO;
|
||||
eaxBufferProperties.flOcclusionDirectRatio = EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO;
|
||||
eaxBufferProperties.lExclusion = EAXBUFFER_DEFAULTEXCLUSION;
|
||||
eaxBufferProperties.flExclusionLFRatio = EAXBUFFER_DEFAULTEXCLUSIONLFRATIO;
|
||||
eaxBufferProperties.lOutsideVolumeHF = EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF;
|
||||
eaxBufferProperties.flDopplerFactor = EAXBUFFER_DEFAULTDOPPLERFACTOR;
|
||||
eaxBufferProperties.flRolloffFactor = EAXBUFFER_DEFAULTROLLOFFFACTOR;
|
||||
eaxBufferProperties.flRoomRolloffFactor = EAXBUFFER_DEFAULTROOMROLLOFFFACTOR;
|
||||
eaxBufferProperties.flAirAbsorptionFactor = EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR;
|
||||
eaxBufferProperties.ulFlags = EAXBUFFER_DEFAULTFLAGS;
|
||||
|
||||
/*
|
||||
Apply the defaults to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[i]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set the reverb properties on the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX3::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the channel reverb properties
|
||||
*/
|
||||
eaxBufferProperties.lDirect = prop->Direct;
|
||||
eaxBufferProperties.lDirectHF = prop->DirectHF;
|
||||
eaxBufferProperties.lRoom = prop->Room;
|
||||
eaxBufferProperties.lRoomHF = prop->RoomHF;
|
||||
eaxBufferProperties.lObstruction = prop->Obstruction;
|
||||
eaxBufferProperties.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
eaxBufferProperties.lOcclusion = prop->Occlusion;
|
||||
eaxBufferProperties.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
eaxBufferProperties.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
eaxBufferProperties.flOcclusionDirectRatio = prop->OcclusionDirectRatio;
|
||||
eaxBufferProperties.lExclusion = prop->Exclusion;
|
||||
eaxBufferProperties.flExclusionLFRatio = prop->ExclusionLFRatio;
|
||||
eaxBufferProperties.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
eaxBufferProperties.flDopplerFactor = prop->DopplerFactor;
|
||||
eaxBufferProperties.flRolloffFactor = prop->RolloffFactor;
|
||||
eaxBufferProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxBufferProperties.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
eaxBufferProperties.ulFlags = prop->Flags;
|
||||
|
||||
/*
|
||||
Apply the values to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[i]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Get the reverb properties from the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX3::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXBUFFERPROPERTIES eaxBufferProperties;
|
||||
GUID eaxBufferGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxBufferGuid, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Get the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxBufferGuid, DSPROPERTY_EAXBUFFER_ALLPARAMETERS, mSources[0]->sid, &eaxBufferProperties, sizeof(EAXBUFFERPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
FMOD_memset(prop, 0, sizeof(FMOD_REVERB_CHANNELPROPERTIES));
|
||||
prop->Direct = eaxBufferProperties.lDirect;
|
||||
prop->DirectHF = eaxBufferProperties.lDirectHF;
|
||||
prop->Room = eaxBufferProperties.lRoom;
|
||||
prop->RoomHF = eaxBufferProperties.lRoomHF;
|
||||
prop->Obstruction = eaxBufferProperties.lObstruction;
|
||||
prop->ObstructionLFRatio = eaxBufferProperties.flObstructionLFRatio;
|
||||
prop->Occlusion = eaxBufferProperties.lOcclusion;
|
||||
prop->OcclusionLFRatio = eaxBufferProperties.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = eaxBufferProperties.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = eaxBufferProperties.flOcclusionDirectRatio;
|
||||
prop->Exclusion = eaxBufferProperties.lExclusion;
|
||||
prop->ExclusionLFRatio = eaxBufferProperties.flExclusionLFRatio;
|
||||
prop->OutsideVolumeHF = eaxBufferProperties.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = eaxBufferProperties.flDopplerFactor;
|
||||
prop->RolloffFactor = eaxBufferProperties.flRolloffFactor;
|
||||
prop->RoomRolloffFactor = eaxBufferProperties.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = eaxBufferProperties.flAirAbsorptionFactor;
|
||||
prop->Flags = eaxBufferProperties.ulFlags;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
29
fmod/win32/src/fmod_channel_openal_eax3.h
Executable file
29
fmod/win32/src/fmod_channel_openal_eax3.h
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef _FMOD_CHANNEL_OPENAL_EAX3_H
|
||||
#define _FMOD_CHANNEL_OPENAL_EAX3_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelOpenALEAX3 : public ChannelOpenAL
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelOpenALEAX3() {};
|
||||
|
||||
FMOD_RESULT setupChannel ();
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* _FMOD_CHANNEL_OPENAL_EAX3_H */
|
||||
392
fmod/win32/src/fmod_channel_openal_eax4.cpp
Executable file
392
fmod/win32/src/fmod_channel_openal_eax4.cpp
Executable file
|
|
@ -0,0 +1,392 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal_eax4.h"
|
||||
#include "fmod_eax4.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Initialise this channel for EAX4 specific settings
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
This will also reset the sources back to defaults when a new channel
|
||||
is reusing sources
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX4::setupChannel()
|
||||
{
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlotNull;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlotNull, &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default slot 0 to on
|
||||
*/
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlotNull, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default channel reverb properties
|
||||
*/
|
||||
eaxSourceProperties.lDirect = EAXSOURCE_DEFAULTDIRECT;
|
||||
eaxSourceProperties.lDirectHF = EAXSOURCE_DEFAULTDIRECTHF;
|
||||
eaxSourceProperties.lRoom = EAXSOURCE_DEFAULTROOM;
|
||||
eaxSourceProperties.lRoomHF = EAXSOURCE_DEFAULTROOMHF;
|
||||
eaxSourceProperties.lObstruction = EAXSOURCE_DEFAULTOBSTRUCTION;
|
||||
eaxSourceProperties.flObstructionLFRatio = EAXSOURCE_DEFAULTOBSTRUCTIONLFRATIO;
|
||||
eaxSourceProperties.lOcclusion = EAXSOURCE_DEFAULTOCCLUSION;
|
||||
eaxSourceProperties.flOcclusionLFRatio = EAXSOURCE_DEFAULTOCCLUSIONLFRATIO;
|
||||
eaxSourceProperties.flOcclusionRoomRatio = EAXSOURCE_DEFAULTOCCLUSIONROOMRATIO;
|
||||
eaxSourceProperties.flOcclusionDirectRatio = EAXSOURCE_DEFAULTOCCLUSIONDIRECTRATIO;
|
||||
eaxSourceProperties.lExclusion = EAXSOURCE_DEFAULTEXCLUSION;
|
||||
eaxSourceProperties.flExclusionLFRatio = EAXSOURCE_DEFAULTEXCLUSIONLFRATIO;
|
||||
eaxSourceProperties.lOutsideVolumeHF = EAXSOURCE_DEFAULTOUTSIDEVOLUMEHF;
|
||||
eaxSourceProperties.flDopplerFactor = EAXSOURCE_DEFAULTDOPPLERFACTOR;
|
||||
eaxSourceProperties.flRolloffFactor = EAXSOURCE_DEFAULTROLLOFFFACTOR;
|
||||
eaxSourceProperties.flRoomRolloffFactor = EAXSOURCE_DEFAULTROOMROLLOFFFACTOR;
|
||||
eaxSourceProperties.flAirAbsorptionFactor = EAXSOURCE_DEFAULTAIRABSORPTIONFACTOR;
|
||||
eaxSourceProperties.ulFlags = EAXSOURCE_DEFAULTFLAGS;
|
||||
|
||||
/*
|
||||
Apply the defaults to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[i]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[i]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set the reverb properties on the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
EAX4 has 4 effects slots, but can only have 2 active on any one source.
|
||||
The first slot is dedicated to reverb, the second slot is dedicated chorus,
|
||||
any of the remaining two slots can be tasked for reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX4::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
unsigned long eaxSourceFlags;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlot2, eaxFXSlot3, eaxFXSlotNull;
|
||||
int numActiveSlots;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot2, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot3, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlotNull, &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Only support a maximum 2 active slots per channel
|
||||
*/
|
||||
numActiveSlots = 0;
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (numActiveSlots > 2)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
Store the slot IDs for the chosen environment
|
||||
*/
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlotNull, sizeof(GUID));
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot2, sizeof(GUID));
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot2, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot2, sizeof(GUID));
|
||||
}
|
||||
else // Set to Slot 0 by default
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
}
|
||||
|
||||
/*
|
||||
Set the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[0]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
eaxSourceProperties.lDirect = prop->Direct;
|
||||
eaxSourceProperties.lDirectHF = prop->DirectHF;
|
||||
eaxSourceProperties.lRoom = prop->Room;
|
||||
eaxSourceProperties.lRoomHF = prop->RoomHF;
|
||||
eaxSourceProperties.lObstruction = prop->Obstruction;
|
||||
eaxSourceProperties.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
eaxSourceProperties.lOcclusion = prop->Occlusion;
|
||||
eaxSourceProperties.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
eaxSourceProperties.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
eaxSourceProperties.flOcclusionDirectRatio = prop->OcclusionDirectRatio;
|
||||
eaxSourceProperties.lExclusion = prop->Exclusion;
|
||||
eaxSourceProperties.flExclusionLFRatio = prop->ExclusionLFRatio;
|
||||
eaxSourceProperties.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
eaxSourceProperties.flDopplerFactor = prop->DopplerFactor;
|
||||
eaxSourceProperties.flRolloffFactor = prop->RolloffFactor;
|
||||
eaxSourceProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxSourceProperties.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_DIRECTHFAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_DIRECTHFAUTO);
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_ROOMAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_ROOMAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_ROOMAUTO);
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_ROOMHFAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_ROOMHFAUTO);
|
||||
eaxSourceProperties.ulFlags = eaxSourceFlags;
|
||||
|
||||
/*
|
||||
Apply the active slots and properties to the sources
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[i]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[i]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Get the reverb properties from the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
EAX4 has 4 effects slots, but can only have 2 active on any one source.
|
||||
The first slot is dedicated to reverb, the second slot is dedicated chorus,
|
||||
any of the remaining two slots can be tasked for reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX4::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlot2, eaxFXSlot3;
|
||||
int numInactiveSlots;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot2, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot3, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Get the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[0]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
FMOD_memset(prop, 0, sizeof(FMOD_REVERB_CHANNELPROPERTIES));
|
||||
prop->Direct = eaxSourceProperties.lDirect;
|
||||
prop->DirectHF = eaxSourceProperties.lDirectHF;
|
||||
prop->Room = eaxSourceProperties.lRoom;
|
||||
prop->RoomHF = eaxSourceProperties.lRoomHF;
|
||||
prop->Obstruction = eaxSourceProperties.lObstruction;
|
||||
prop->ObstructionLFRatio = eaxSourceProperties.flObstructionLFRatio;
|
||||
prop->Occlusion = eaxSourceProperties.lOcclusion;
|
||||
prop->OcclusionLFRatio = eaxSourceProperties.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = eaxSourceProperties.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = eaxSourceProperties.flOcclusionDirectRatio;
|
||||
prop->Exclusion = eaxSourceProperties.lExclusion;
|
||||
prop->ExclusionLFRatio = eaxSourceProperties.flExclusionLFRatio;
|
||||
prop->OutsideVolumeHF = eaxSourceProperties.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = eaxSourceProperties.flDopplerFactor;
|
||||
prop->RolloffFactor = eaxSourceProperties.flRolloffFactor;
|
||||
prop->RoomRolloffFactor = eaxSourceProperties.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = eaxSourceProperties.flAirAbsorptionFactor;
|
||||
|
||||
prop->Flags = 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_DIRECTHFAUTO) ? FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO : 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_ROOMAUTO) ? FMOD_REVERB_CHANNELFLAGS_ROOMAUTO : 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_ROOMHFAUTO) ? FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO : 0;
|
||||
|
||||
// Get all the effect slots associated with this source
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[0]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
/*
|
||||
See if there are any active effect slots
|
||||
*/
|
||||
numInactiveSlots = 0;
|
||||
|
||||
// Check active slot 0 for any of the 3 possible effect IDs
|
||||
if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE3;
|
||||
}
|
||||
else
|
||||
{
|
||||
numInactiveSlots++;
|
||||
}
|
||||
|
||||
// Check active slot 1 for any of the 3 possible effect IDs
|
||||
if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE3;
|
||||
}
|
||||
else
|
||||
{
|
||||
numInactiveSlots++;
|
||||
}
|
||||
|
||||
// If no slots have been assigned (max slots = 2), assign to slot 0
|
||||
if (numInactiveSlots == 2)
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
29
fmod/win32/src/fmod_channel_openal_eax4.h
Executable file
29
fmod/win32/src/fmod_channel_openal_eax4.h
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef _FMOD_CHANNEL_OPENAL_EAX4_H
|
||||
#define _FMOD_CHANNEL_OPENAL_EAX4_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelOpenALEAX4 : public ChannelOpenAL
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelOpenALEAX4() {};
|
||||
|
||||
FMOD_RESULT setupChannel ();
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* _FMOD_CHANNEL_OPENAL_EAX4_H */
|
||||
633
fmod/win32/src/fmod_channel_openal_eax5.cpp
Executable file
633
fmod/win32/src/fmod_channel_openal_eax5.cpp
Executable file
|
|
@ -0,0 +1,633 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal_eax5.h"
|
||||
#include "fmod_eax5.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Initialise this channel for EAX5 specific settings
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
This will also reset the sources back to defaults when a new channel
|
||||
is reusing sources
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX5::setupChannel()
|
||||
{
|
||||
EAXSPEAKERLEVELPROPERTIES eaxSourceSpeakerLevels[8];
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlotNull;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX50_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlotNull, &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default speaker levels
|
||||
*/
|
||||
eaxSourceSpeakerLevels[0].lSpeakerID = EAXSPEAKER_FRONT_LEFT;
|
||||
eaxSourceSpeakerLevels[0].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[1].lSpeakerID = EAXSPEAKER_FRONT_CENTER;
|
||||
eaxSourceSpeakerLevels[1].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[2].lSpeakerID = EAXSPEAKER_FRONT_RIGHT;
|
||||
eaxSourceSpeakerLevels[2].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[3].lSpeakerID = EAXSPEAKER_SIDE_RIGHT;
|
||||
eaxSourceSpeakerLevels[3].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[4].lSpeakerID = EAXSPEAKER_REAR_RIGHT;
|
||||
eaxSourceSpeakerLevels[4].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[5].lSpeakerID = EAXSPEAKER_REAR_LEFT;
|
||||
eaxSourceSpeakerLevels[5].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[6].lSpeakerID = EAXSPEAKER_SIDE_LEFT;
|
||||
eaxSourceSpeakerLevels[6].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
eaxSourceSpeakerLevels[7].lSpeakerID = EAXSPEAKER_LOW_FREQUENCY;
|
||||
eaxSourceSpeakerLevels[7].lLevel = EAXSOURCE_DEFAULTSPEAKERLEVEL;
|
||||
|
||||
/*
|
||||
Set the default slot 0 to on
|
||||
*/
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[2], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[3], &eaxFXSlotNull, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Set the default channel reverb properties
|
||||
*/
|
||||
eaxSourceProperties.lDirect = EAXSOURCE_DEFAULTDIRECT;
|
||||
eaxSourceProperties.lDirectHF = EAXSOURCE_DEFAULTDIRECTHF;
|
||||
eaxSourceProperties.lRoom = EAXSOURCE_DEFAULTROOM;
|
||||
eaxSourceProperties.lRoomHF = EAXSOURCE_DEFAULTROOMHF;
|
||||
eaxSourceProperties.lObstruction = EAXSOURCE_DEFAULTOBSTRUCTION;
|
||||
eaxSourceProperties.flObstructionLFRatio = EAXSOURCE_DEFAULTOBSTRUCTIONLFRATIO;
|
||||
eaxSourceProperties.lOcclusion = EAXSOURCE_DEFAULTOCCLUSION;
|
||||
eaxSourceProperties.flOcclusionLFRatio = EAXSOURCE_DEFAULTOCCLUSIONLFRATIO;
|
||||
eaxSourceProperties.flOcclusionRoomRatio = EAXSOURCE_DEFAULTOCCLUSIONROOMRATIO;
|
||||
eaxSourceProperties.flOcclusionDirectRatio = EAXSOURCE_DEFAULTOCCLUSIONDIRECTRATIO;
|
||||
eaxSourceProperties.lExclusion = EAXSOURCE_DEFAULTEXCLUSION;
|
||||
eaxSourceProperties.flExclusionLFRatio = EAXSOURCE_DEFAULTEXCLUSIONLFRATIO;
|
||||
eaxSourceProperties.lOutsideVolumeHF = EAXSOURCE_DEFAULTOUTSIDEVOLUMEHF;
|
||||
eaxSourceProperties.flDopplerFactor = EAXSOURCE_DEFAULTDOPPLERFACTOR;
|
||||
eaxSourceProperties.flRolloffFactor = EAXSOURCE_DEFAULTROLLOFFFACTOR;
|
||||
eaxSourceProperties.flRoomRolloffFactor = EAXSOURCE_DEFAULTROOMROLLOFFFACTOR;
|
||||
eaxSourceProperties.flAirAbsorptionFactor = EAXSOURCE_DEFAULTAIRABSORPTIONFACTOR;
|
||||
eaxSourceProperties.flMacroFXFactor = EAXSOURCE_DEFAULTMACROFXFACTOR;
|
||||
eaxSourceProperties.ulFlags = EAXSOURCE_DEFAULTFLAGS;
|
||||
|
||||
/*
|
||||
Apply the defaults to each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_SPEAKERLEVELS, mSources[i]->sid, &eaxSourceSpeakerLevels, 8 * sizeof(EAXSPEAKERLEVELPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[i]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[i]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Sets the channel's speaker volume levels for each speaker individually
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX5::setSpeakerMix(float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright)
|
||||
{
|
||||
EAXSPEAKERLEVELPROPERTIES eaxSourceSpeakerLevels[8];
|
||||
unsigned long eaxSourceFlags;
|
||||
GUID eaxSourceGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
eaxSourceSpeakerLevels[0].lSpeakerID = EAXSPEAKER_FRONT_LEFT;
|
||||
eaxSourceSpeakerLevels[0].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, frontleft)));
|
||||
|
||||
eaxSourceSpeakerLevels[1].lSpeakerID = EAXSPEAKER_FRONT_CENTER;
|
||||
eaxSourceSpeakerLevels[1].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, center)));
|
||||
|
||||
eaxSourceSpeakerLevels[2].lSpeakerID = EAXSPEAKER_FRONT_RIGHT;
|
||||
eaxSourceSpeakerLevels[2].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, frontright)));
|
||||
|
||||
eaxSourceSpeakerLevels[3].lSpeakerID = EAXSPEAKER_SIDE_RIGHT;
|
||||
eaxSourceSpeakerLevels[3].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, sideright)));
|
||||
|
||||
eaxSourceSpeakerLevels[4].lSpeakerID = EAXSPEAKER_REAR_RIGHT;
|
||||
eaxSourceSpeakerLevels[4].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, backright)));
|
||||
|
||||
eaxSourceSpeakerLevels[5].lSpeakerID = EAXSPEAKER_REAR_LEFT;
|
||||
eaxSourceSpeakerLevels[5].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, backleft)));
|
||||
|
||||
eaxSourceSpeakerLevels[6].lSpeakerID = EAXSPEAKER_SIDE_LEFT;
|
||||
eaxSourceSpeakerLevels[6].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, sideleft)));
|
||||
|
||||
eaxSourceSpeakerLevels[7].lSpeakerID = EAXSPEAKER_LOW_FREQUENCY;
|
||||
eaxSourceSpeakerLevels[7].lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, lfe)));
|
||||
|
||||
/*
|
||||
Enable or disable speaker mode usage for OpenAL
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[0]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
if (mParent->m3DPanLevel >= 0.5f)
|
||||
{
|
||||
eaxSourceFlags |= EAXSOURCEFLAGS_APPLYSPEAKERLEVELS;
|
||||
}
|
||||
else
|
||||
{
|
||||
eaxSourceFlags &= ~EAXSOURCEFLAGS_APPLYSPEAKERLEVELS;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the speaker levels for each source
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[i]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_SPEAKERLEVELS, mSources[i]->sid, &eaxSourceSpeakerLevels, 8 * sizeof(EAXSPEAKERLEVELPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Sets the incoming sound levels for a particular speaker
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX5::setSpeakerLevels(int speaker, float *levels, int numlevels)
|
||||
{
|
||||
long FMOD_SPEAKER_TO_EAXSPEAKER[11] = { EAXSPEAKER_FRONT_LEFT, EAXSPEAKER_FRONT_RIGHT, EAXSPEAKER_FRONT_CENTER, EAXSPEAKER_LOW_FREQUENCY, EAXSPEAKER_REAR_LEFT, EAXSPEAKER_REAR_RIGHT, EAXSPEAKER_SIDE_LEFT, EAXSPEAKER_SIDE_RIGHT, EAXSPEAKER_FRONT_LEFT, EAXSPEAKER_FRONT_LEFT, EAXSPEAKER_REAR_CENTER };
|
||||
EAXSPEAKERLEVELPROPERTIES eaxSourceSpeakerLevels;
|
||||
unsigned long eaxSourceFlags;
|
||||
GUID eaxSourceGuid;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Enable or disable speaker mode usage for OpenAL
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[0]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
if (mParent->m3DPanLevel >= 0.5f)
|
||||
{
|
||||
eaxSourceFlags |= EAXSOURCEFLAGS_APPLYSPEAKERLEVELS;
|
||||
}
|
||||
else
|
||||
{
|
||||
eaxSourceFlags &= ~EAXSOURCEFLAGS_APPLYSPEAKERLEVELS;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the speaker levels for each source, there may be less sources than levels
|
||||
*/
|
||||
numlevels = (mNumSources < numlevels) ? mNumSources : numlevels;
|
||||
for (int i = 0; i < numlevels; i++)
|
||||
{
|
||||
eaxSourceSpeakerLevels.lSpeakerID = FMOD_SPEAKER_TO_EAXSPEAKER[speaker];
|
||||
eaxSourceSpeakerLevels.lLevel = (long)(100.0f * 20.0f * FMOD_LOG10(max(0.00001f, levels[i])));
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[i]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_SPEAKERLEVELS, mSources[i]->sid, &eaxSourceSpeakerLevels, sizeof(EAXSPEAKERLEVELPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set the reverb properties on the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
EAX5 has 4 effects slots, and is currently set up to allow only 2 to be active on
|
||||
any one source, any of the four slots can be tasked for reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX5::setReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
unsigned long eaxSourceFlags;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlot1, eaxFXSlot2, eaxFXSlot3, eaxFXSlotNull;
|
||||
int numActiveSlots;
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX50_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot1, &FMOD_EAXPROPERTYID_EAX50_FXSlot1, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot2, &FMOD_EAXPROPERTYID_EAX50_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot3, &FMOD_EAXPROPERTYID_EAX50_FXSlot3, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlotNull, &FMOD_EAX_NULL_GUID, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Only support a maximum 2 active slots per channel
|
||||
*/
|
||||
numActiveSlots = 0;
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE3)
|
||||
{
|
||||
numActiveSlots++;
|
||||
}
|
||||
if (numActiveSlots > 2)
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
Store the slot IDs for the chosen environment
|
||||
*/
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[2], &eaxFXSlotNull, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[3], &eaxFXSlotNull, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE0)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot1, sizeof(GUID));
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot2, sizeof(GUID));
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE3)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE1)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot1, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot2, sizeof(GUID));
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE3)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE2)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot2, sizeof(GUID));
|
||||
|
||||
if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE3)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else if (prop->Flags & FMOD_REVERB_CHANNELFLAGS_INSTANCE3)
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot3, sizeof(GUID));
|
||||
}
|
||||
else // Set to Slot 0 by default
|
||||
{
|
||||
FMOD_memcpy(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID));
|
||||
}
|
||||
|
||||
/*
|
||||
Set the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_FLAGS, mSources[0]->sid, &eaxSourceFlags, sizeof(unsigned long));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
eaxSourceProperties.lDirect = prop->Direct;
|
||||
eaxSourceProperties.lDirectHF = prop->DirectHF;
|
||||
eaxSourceProperties.lRoom = prop->Room;
|
||||
eaxSourceProperties.lRoomHF = prop->RoomHF;
|
||||
eaxSourceProperties.lObstruction = prop->Obstruction;
|
||||
eaxSourceProperties.flObstructionLFRatio = prop->ObstructionLFRatio;
|
||||
eaxSourceProperties.lOcclusion = prop->Occlusion;
|
||||
eaxSourceProperties.flOcclusionLFRatio = prop->OcclusionLFRatio;
|
||||
eaxSourceProperties.flOcclusionRoomRatio = prop->OcclusionRoomRatio;
|
||||
eaxSourceProperties.flOcclusionDirectRatio = prop->OcclusionDirectRatio;
|
||||
eaxSourceProperties.lExclusion = prop->Exclusion;
|
||||
eaxSourceProperties.flExclusionLFRatio = prop->ExclusionLFRatio;
|
||||
eaxSourceProperties.lOutsideVolumeHF = prop->OutsideVolumeHF;
|
||||
eaxSourceProperties.flDopplerFactor = prop->DopplerFactor;
|
||||
eaxSourceProperties.flRolloffFactor = prop->RolloffFactor;
|
||||
eaxSourceProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxSourceProperties.flAirAbsorptionFactor = prop->AirAbsorptionFactor;
|
||||
eaxSourceProperties.flMacroFXFactor = EAXSOURCE_DEFAULTMACROFXFACTOR;
|
||||
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_DIRECTHFAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_DIRECTHFAUTO);
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_ROOMAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_ROOMAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_ROOMAUTO);
|
||||
eaxSourceFlags = (prop->Flags & FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO) ? (eaxSourceFlags | EAXSOURCEFLAGS_ROOMHFAUTO) : (eaxSourceFlags & ~EAXSOURCEFLAGS_ROOMHFAUTO);
|
||||
eaxSourceProperties.ulFlags = eaxSourceFlags;
|
||||
|
||||
/*
|
||||
Apply the active slots and properties to the sources
|
||||
*/
|
||||
for (int i = 0; i < mNumSources; i++)
|
||||
{
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[i]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
mOutputOAL->mEAXSet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[i]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Get the reverb properties from the hardware
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
EAX5 has 4 effects slots, and is currently set up to allow only 2 to be active on
|
||||
any one source, any of the four slots can be tasked for reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT ChannelOpenALEAX5::getReverbProperties(FMOD_REVERB_CHANNELPROPERTIES *prop)
|
||||
{
|
||||
EAXSOURCEPROPERTIES eaxSourceProperties;
|
||||
EAXACTIVEFXSLOTS eaxSlots;
|
||||
GUID eaxSourceGuid;
|
||||
GUID eaxFXSlot0, eaxFXSlot1, eaxFXSlot2, eaxFXSlot3;
|
||||
int numInactiveSlots;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mOutputOAL)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&eaxFXSlot0, &FMOD_EAXPROPERTYID_EAX50_FXSlot0, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot1, &FMOD_EAXPROPERTYID_EAX50_FXSlot1, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot2, &FMOD_EAXPROPERTYID_EAX50_FXSlot2, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxFXSlot3, &FMOD_EAXPROPERTYID_EAX50_FXSlot3, sizeof(GUID));
|
||||
FMOD_memcpy(&eaxSourceGuid, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Get the channel reverb properties
|
||||
*/
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_ALLPARAMETERS, mSources[0]->sid, &eaxSourceProperties, sizeof(EAXSOURCEPROPERTIES));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
FMOD_memset(prop, 0, sizeof(FMOD_REVERB_CHANNELPROPERTIES));
|
||||
prop->Direct = eaxSourceProperties.lDirect;
|
||||
prop->DirectHF = eaxSourceProperties.lDirectHF;
|
||||
prop->Room = eaxSourceProperties.lRoom;
|
||||
prop->RoomHF = eaxSourceProperties.lRoomHF;
|
||||
prop->Obstruction = eaxSourceProperties.lObstruction;
|
||||
prop->ObstructionLFRatio = eaxSourceProperties.flObstructionLFRatio;
|
||||
prop->Occlusion = eaxSourceProperties.lOcclusion;
|
||||
prop->OcclusionLFRatio = eaxSourceProperties.flOcclusionLFRatio;
|
||||
prop->OcclusionRoomRatio = eaxSourceProperties.flOcclusionRoomRatio;
|
||||
prop->OcclusionDirectRatio = eaxSourceProperties.flOcclusionDirectRatio;
|
||||
prop->Exclusion = eaxSourceProperties.lExclusion;
|
||||
prop->ExclusionLFRatio = eaxSourceProperties.flExclusionLFRatio;
|
||||
prop->OutsideVolumeHF = eaxSourceProperties.lOutsideVolumeHF;
|
||||
prop->DopplerFactor = eaxSourceProperties.flDopplerFactor;
|
||||
prop->RolloffFactor = eaxSourceProperties.flRolloffFactor;
|
||||
prop->RoomRolloffFactor = eaxSourceProperties.flRoomRolloffFactor;
|
||||
prop->AirAbsorptionFactor = eaxSourceProperties.flAirAbsorptionFactor;
|
||||
|
||||
prop->Flags = 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_DIRECTHFAUTO) ? FMOD_REVERB_CHANNELFLAGS_DIRECTHFAUTO : 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_ROOMAUTO) ? FMOD_REVERB_CHANNELFLAGS_ROOMAUTO : 0;
|
||||
prop->Flags |= (eaxSourceProperties.ulFlags & EAXSOURCEFLAGS_ROOMHFAUTO) ? FMOD_REVERB_CHANNELFLAGS_ROOMHFAUTO : 0;
|
||||
|
||||
// Get all the effect slots associated with this source
|
||||
mOutputOAL->mEAXGet(&eaxSourceGuid, EAXSOURCE_ACTIVEFXSLOTID, mSources[0]->sid, &eaxSlots, sizeof(EAXACTIVEFXSLOTS));
|
||||
if (mOutputOAL->mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
/*
|
||||
See if there are any active effect slots
|
||||
*/
|
||||
numInactiveSlots = 0;
|
||||
|
||||
// Check active slot 0 for any of the 4 possible effect IDs
|
||||
if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot1, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE1;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[0], &eaxFXSlot3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE3;
|
||||
}
|
||||
else
|
||||
{
|
||||
numInactiveSlots++;
|
||||
}
|
||||
|
||||
// Check active slot 1 for any of the 4 possible effect IDs
|
||||
if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot0, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot1, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE1;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot2, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE2;
|
||||
}
|
||||
else if (!memcmp(&eaxSlots.guidActiveFXSlots[1], &eaxFXSlot3, sizeof(GUID)))
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE3;
|
||||
}
|
||||
else
|
||||
{
|
||||
numInactiveSlots++;
|
||||
}
|
||||
|
||||
// If no slots have been assigned (max slots = 2), assign to slot 0
|
||||
if (numInactiveSlots == 2)
|
||||
{
|
||||
prop->Flags |= FMOD_REVERB_CHANNELFLAGS_INSTANCE0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
32
fmod/win32/src/fmod_channel_openal_eax5.h
Executable file
32
fmod/win32/src/fmod_channel_openal_eax5.h
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef _FMOD_CHANNEL_OPENAL_EAX5_H
|
||||
#define _FMOD_CHANNEL_OPENAL_EAX5_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_channel_openal.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelOpenALEAX5 : public ChannelOpenAL
|
||||
{
|
||||
public:
|
||||
|
||||
ChannelOpenALEAX5() {};
|
||||
|
||||
FMOD_RESULT setupChannel ();
|
||||
|
||||
FMOD_RESULT setSpeakerMix (float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright);
|
||||
FMOD_RESULT setSpeakerLevels (int speaker, float *levels, int numlevels);
|
||||
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* _FMOD_CHANNEL_OPENAL_EAX5_H */
|
||||
1180
fmod/win32/src/fmod_codec_asf.cpp
Executable file
1180
fmod/win32/src/fmod_codec_asf.cpp
Executable file
File diff suppressed because it is too large
Load diff
131
fmod/win32/src/fmod_codec_asf.h
Executable file
131
fmod/win32/src/fmod_codec_asf.h
Executable file
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef _FMOD_CODEC_ASF_H
|
||||
#define _FMOD_CODEC_ASF_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_ASF
|
||||
|
||||
#include "fmod_codeci.h"
|
||||
|
||||
#include <objidl.h>
|
||||
#include "../lib/wmsdk/include/wmsdk.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class CROStream : public IStream
|
||||
{
|
||||
public:
|
||||
|
||||
CROStream();
|
||||
|
||||
//
|
||||
// IUnknown methods
|
||||
//
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid,
|
||||
/* [out] */ void **ppvObject );
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
//
|
||||
// Methods of IStream
|
||||
//
|
||||
HRESULT STDMETHODCALLTYPE Read( void *pv, ULONG cb, ULONG *pcbRead );
|
||||
HRESULT STDMETHODCALLTYPE Seek( LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition );
|
||||
HRESULT STDMETHODCALLTYPE Stat( STATSTG *pstatstg, DWORD grfStatFlag );
|
||||
|
||||
//
|
||||
// Non-implemented methods of IStream
|
||||
//
|
||||
HRESULT STDMETHODCALLTYPE Write( void const *pv, ULONG cb, ULONG *pcbWritten )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE SetSize( ULARGE_INTEGER libNewSize )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE CopyTo( IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Commit( DWORD grfCommitFlags )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Revert()
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE LockRegion( ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE UnlockRegion( ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Clone( IStream **ppstm )
|
||||
{
|
||||
return( E_NOTIMPL );
|
||||
}
|
||||
|
||||
//
|
||||
// CROStream method
|
||||
//
|
||||
HRESULT Open( /* [in] */ LPCTSTR ptszURL );
|
||||
|
||||
protected:
|
||||
|
||||
~CROStream();
|
||||
|
||||
File *mFile;
|
||||
LONG m_cRefs;
|
||||
};
|
||||
|
||||
typedef HRESULT (STDMETHODCALLTYPE *PFN_WMCREATESYNCREADER)( IUnknown* pUnkCert, DWORD dwRights, IWMSyncReader **ppSyncReader );
|
||||
|
||||
class SyncPointNamed;
|
||||
|
||||
static const unsigned int FMOD_ASF_MAXIMUM_SEEK_POS_MS = 2000;
|
||||
|
||||
class CodecASF : public Codec
|
||||
{
|
||||
private:
|
||||
|
||||
bool mCoInitialized;
|
||||
IWMSyncReader *mReader; // IWMReader pointer
|
||||
CROStream *mStream;
|
||||
WORD mAudioStreamNum;
|
||||
WORD mVideoStreamNum;
|
||||
QWORD mSampleTime;
|
||||
bool mSeekable;
|
||||
int mNumSyncPoints;
|
||||
SyncPointNamed *mSyncPoint;
|
||||
unsigned int mExcessBytes;
|
||||
|
||||
static PFN_WMCREATESYNCREADER gWMCreateSyncReader;
|
||||
static HMODULE gDLLHandle;
|
||||
|
||||
FMOD_RESULT getStreamNumbers(IWMProfile* pProfile);
|
||||
|
||||
FMOD_RESULT openInternal(FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
||||
FMOD_RESULT closeInternal();
|
||||
FMOD_RESULT readInternal(void *buffer, unsigned int size, unsigned int *read);
|
||||
FMOD_RESULT setPositionInternal(int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
||||
FMOD_RESULT soundCreateInternal(int subsound, FMOD_SOUND *sound);
|
||||
|
||||
public:
|
||||
|
||||
static FMOD_RESULT F_CALLBACK openCallback(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback(FMOD_CODEC_STATE *codec);
|
||||
static FMOD_RESULT F_CALLBACK readCallback(FMOD_CODEC_STATE *codec, void *buffer, unsigned int sizebytes, unsigned int *bytesread);
|
||||
static FMOD_RESULT F_CALLBACK setPositionCallback(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
||||
static FMOD_RESULT F_CALLBACK soundCreateCallback(FMOD_CODEC_STATE *codec, int subsound, FMOD_SOUND *sound);
|
||||
|
||||
static FMOD_CODEC_DESCRIPTION_EX *getDescriptionEx();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_ASF */
|
||||
|
||||
#endif
|
||||
373
fmod/win32/src/fmod_codec_cdda.cpp
Executable file
373
fmod/win32/src/fmod_codec_cdda.cpp
Executable file
|
|
@ -0,0 +1,373 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_CDDA
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_codec_cdda.h"
|
||||
#include "fmod_debug.h"
|
||||
#include "fmod_file.h"
|
||||
#include "fmod_file_cdda.h"
|
||||
#include "fmod_metadata.h"
|
||||
#include "fmod_os_cdda.h"
|
||||
#include "fmod_soundi.h"
|
||||
#include "fmod_string.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
FMOD_CODEC_DESCRIPTION_EX cddacodec;
|
||||
|
||||
|
||||
#ifdef PLUGIN_EXPORTS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
FMODGetCodecDescriptionEx is mandatory for every fmod plugin. This is the symbol the registerplugin function searches for.
|
||||
Must be declared with F_API to make it export as stdcall.
|
||||
*/
|
||||
F_DECLSPEC F_DLLEXPORT FMOD_CODEC_DESCRIPTION_EX * F_API FMODGetCodecDescriptionEx()
|
||||
{
|
||||
return CodecCDDA::getDescriptionEx();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PLUGIN_EXPORTS */
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_CODEC_DESCRIPTION_EX *CodecCDDA::getDescriptionEx()
|
||||
{
|
||||
FMOD_memset(&cddacodec, 0, sizeof(FMOD_CODEC_DESCRIPTION_EX));
|
||||
|
||||
cddacodec.name = "FMOD CDDA Codec";
|
||||
cddacodec.version = 0x00010100;
|
||||
cddacodec.timeunits = FMOD_TIMEUNIT_PCM;
|
||||
cddacodec.open = &CodecCDDA::openCallback;
|
||||
cddacodec.close = &CodecCDDA::closeCallback;
|
||||
cddacodec.read = &CodecCDDA::readCallback;
|
||||
cddacodec.setposition = &CodecCDDA::setPositionCallback;
|
||||
|
||||
cddacodec.mType = FMOD_SOUND_TYPE_CDDA;
|
||||
cddacodec.mSize = sizeof(CodecCDDA);
|
||||
|
||||
return &cddacodec;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CodecCDDA::openInternal(FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo)
|
||||
{
|
||||
int count;
|
||||
char *filename;
|
||||
CddaFile *cddafile;
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
|
||||
mCurrentTrack = -1;
|
||||
|
||||
init(FMOD_SOUND_TYPE_CDDA);
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "CodecCDDA::openInternal", "attempting to open as CDDA..\n"));
|
||||
|
||||
mFile->getName(&filename);
|
||||
if (!FMOD_OS_CDDA_IsDeviceName(filename))
|
||||
{
|
||||
return FMOD_ERR_FORMAT;
|
||||
}
|
||||
|
||||
cddafile = SAFE_CAST(CddaFile, mFile);
|
||||
|
||||
result = cddafile->getNumTracks(&numsubsounds);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!numsubsounds)
|
||||
{
|
||||
return FMOD_ERR_CDDA_NOAUDIO;
|
||||
}
|
||||
|
||||
waveformat = (FMOD_CODEC_WAVEFORMAT *)FMOD_Memory_Calloc(sizeof(FMOD_CODEC_WAVEFORMAT) * numsubsounds);
|
||||
if (!waveformat)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
for (count = 0; count < numsubsounds; count++)
|
||||
{
|
||||
unsigned int tracklength;
|
||||
|
||||
result = cddafile->getTrackLength(count, &tracklength);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
sprintf(waveformat[count].name, "Track %d", count+1);
|
||||
waveformat[count].format = FMOD_SOUND_FORMAT_PCM16;
|
||||
waveformat[count].channels = 2;
|
||||
waveformat[count].frequency = 44100;
|
||||
waveformat[count].lengthpcm = tracklength >> 2;
|
||||
waveformat[count].blockalign = waveformat[count].channels * 16 / 8;
|
||||
}
|
||||
|
||||
mPCMBufferLengthBytes = 256 * 1024;
|
||||
|
||||
result = setPositionInternal(0, 0, FMOD_TIMEUNIT_PCM);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CodecCDDA::closeInternal()
|
||||
{
|
||||
if (waveformat)
|
||||
{
|
||||
FMOD_Memory_Free(waveformat);
|
||||
waveformat = 0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CodecCDDA::readInternal(void *buffer, unsigned int sizebytes, unsigned int *bytesread)
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
|
||||
result = mFile->read(buffer, 1, sizebytes, bytesread);
|
||||
if (result != FMOD_OK && result != FMOD_ERR_FILE_EOF)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CodecCDDA::setPositionInternal(int subsound, unsigned int position, FMOD_TIMEUNIT postype)
|
||||
{
|
||||
CddaFile *cddafile;
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
unsigned int offset;
|
||||
|
||||
if (subsound < 0 || (numsubsounds && subsound >= numsubsounds))
|
||||
{
|
||||
return FMOD_ERR_INVALID_POSITION;
|
||||
}
|
||||
|
||||
cddafile = SAFE_CAST(CddaFile, mFile);
|
||||
|
||||
if (subsound != mCurrentTrack)
|
||||
{
|
||||
mCurrentTrack = subsound;
|
||||
|
||||
result = cddafile->openTrack(mCurrentTrack);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = SoundI::getBytesFromSamples(position, &offset, waveformat[mCurrentTrack].channels, waveformat[mCurrentTrack].format);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = cddafile->seek(offset, SEEK_SET);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK CodecCDDA::openCallback(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo)
|
||||
{
|
||||
CodecCDDA *cdda = (CodecCDDA *)codec;
|
||||
|
||||
return cdda->openInternal(usermode, userexinfo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK CodecCDDA::closeCallback(FMOD_CODEC_STATE *codec)
|
||||
{
|
||||
CodecCDDA *cdda = (CodecCDDA *)codec;
|
||||
|
||||
return cdda->closeInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK CodecCDDA::readCallback(FMOD_CODEC_STATE *codec, void *buffer, unsigned int sizebytes, unsigned int *bytesread)
|
||||
{
|
||||
CodecCDDA *cdda = (CodecCDDA *)codec;
|
||||
|
||||
return cdda->readInternal(buffer, sizebytes, bytesread);
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK CodecCDDA::setPositionCallback(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype)
|
||||
{
|
||||
CodecCDDA *cdda = (CodecCDDA *)codec;
|
||||
|
||||
return cdda->setPositionInternal(subsound, position, postype);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
36
fmod/win32/src/fmod_codec_cdda.h
Executable file
36
fmod/win32/src/fmod_codec_cdda.h
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _FMOD_CODEC_CDDA_H
|
||||
#define _FMOD_CODEC_CDDA_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_CDDA
|
||||
|
||||
#include "fmod_codeci.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class CodecCDDA : public Codec
|
||||
{
|
||||
private:
|
||||
|
||||
int mCurrentTrack;
|
||||
|
||||
FMOD_RESULT openInternal(FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
||||
FMOD_RESULT closeInternal();
|
||||
FMOD_RESULT readInternal(void *buffer, unsigned int size, unsigned int *read);
|
||||
FMOD_RESULT setPositionInternal(int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
||||
|
||||
public:
|
||||
|
||||
static FMOD_RESULT F_CALLBACK openCallback(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback(FMOD_CODEC_STATE *codec);
|
||||
static FMOD_RESULT F_CALLBACK readCallback(FMOD_CODEC_STATE *codec, void *buffer, unsigned int sizebytes, unsigned int *bytesread);
|
||||
static FMOD_RESULT F_CALLBACK setPositionCallback(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
||||
|
||||
static FMOD_CODEC_DESCRIPTION_EX *getDescriptionEx();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_CDDA */
|
||||
|
||||
#endif
|
||||
6
fmod/win32/src/fmod_dllmain.cpp
Executable file
6
fmod/win32/src/fmod_dllmain.cpp
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
732
fmod/win32/src/fmod_dsp_connection_asm.s
Executable file
732
fmod/win32/src/fmod_dsp_connection_asm.s
Executable file
|
|
@ -0,0 +1,732 @@
|
|||
%include "./FMOD_static/win32/src/c32.mac"
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL UNINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .data use32 align=32]
|
||||
|
||||
; ==========================================================================================
|
||||
; CODE
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .text use32 align=32]
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_MixMonoToStereo_SIMD (float *inbuffer, float *outbuffer, unsigned int length, float lvolume, float rvolume);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_MixMonoToStereo_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$lvolume arg
|
||||
%$rvolume arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [lvolume ][rvolume ][lvolume ][rvolume ]
|
||||
; xmm1 = [samp1 ][samp1 ][samp2 ][samp2 ]
|
||||
; xmm2 = [samp3 ][samp3 ][samp4 ][samp4 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
movss xmm0, [ebp+%$lvolume]
|
||||
movss xmm1, [ebp+%$rvolume]
|
||||
shufps xmm0, xmm0, 0
|
||||
shufps xmm1, xmm1, 0
|
||||
unpcklps xmm0, xmm1
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz mixloopMtoSrolledstart
|
||||
|
||||
mixloopMtoSunrolled:
|
||||
|
||||
movups xmm1, [esi]
|
||||
movaps xmm2, xmm1
|
||||
|
||||
movaps xmm3, [edi]
|
||||
movaps xmm4, [edi + 16]
|
||||
|
||||
unpcklps xmm1, xmm1
|
||||
unpckhps xmm2, xmm2
|
||||
|
||||
mulps xmm1, xmm0
|
||||
mulps xmm2, xmm0
|
||||
|
||||
addps xmm3, xmm1
|
||||
addps xmm4, xmm2
|
||||
|
||||
movaps [edi], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
add edi, 32
|
||||
add esi, 16
|
||||
dec ecx
|
||||
jnz near mixloopMtoSunrolled
|
||||
|
||||
mixloopMtoSrolledstart:
|
||||
|
||||
mov ecx, edx
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mixMtoSdone
|
||||
|
||||
mixloopMtoSrolled:
|
||||
|
||||
movss xmm1, [esi]
|
||||
movss xmm2, xmm1
|
||||
|
||||
movss xmm3, [edi]
|
||||
movss xmm4, [edi+4]
|
||||
|
||||
mulss xmm1, [ebp+%$lvolume]
|
||||
mulss xmm2, [ebp+%$rvolume]
|
||||
|
||||
addss xmm3, xmm1
|
||||
addss xmm4, xmm2
|
||||
|
||||
movss [edi], xmm3
|
||||
movss [edi+4], xmm4
|
||||
|
||||
add edi, 8
|
||||
add esi, 4
|
||||
|
||||
dec ecx
|
||||
jnz near mixloopMtoSrolled
|
||||
|
||||
mixMtoSdone:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
endproc
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_MixStereoToStereo_SIMD(float *inbuffer, float *outbuffer, unsigned int length, float lvolume, float rvolume);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_MixStereoToStereo_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$lvolume arg
|
||||
%$rvolume arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [lvolume ][rvolume ][lvolume ][rvolume ]
|
||||
; xmm1 = [samp1 ][samp1 ][samp2 ][samp2 ]
|
||||
; xmm2 = [samp3 ][samp3 ][samp4 ][samp4 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
movss xmm0, [ebp+%$lvolume]
|
||||
movss xmm1, [ebp+%$rvolume]
|
||||
shufps xmm0, xmm0, 0
|
||||
shufps xmm1, xmm1, 0
|
||||
unpcklps xmm0, xmm1
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz mixloopStoSrolledstart
|
||||
|
||||
mixloopStoSunrolled:
|
||||
|
||||
movups xmm1, [esi]
|
||||
movups xmm2, [esi+16]
|
||||
|
||||
movaps xmm3, [edi]
|
||||
movaps xmm4, [edi+16]
|
||||
|
||||
mulps xmm1, xmm0
|
||||
mulps xmm2, xmm0
|
||||
|
||||
addps xmm3, xmm1
|
||||
addps xmm4, xmm2
|
||||
|
||||
movaps [edi], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
add edi, 32
|
||||
add esi, 32
|
||||
dec ecx
|
||||
jnz near mixloopStoSunrolled
|
||||
|
||||
mixloopStoSrolledstart:
|
||||
|
||||
mov ecx, edx
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mixStoSdone
|
||||
|
||||
mixloopStoSrolled:
|
||||
|
||||
movss xmm1, [esi]
|
||||
movss xmm2, [esi+4]
|
||||
|
||||
movss xmm3, [edi]
|
||||
movss xmm4, [edi+4]
|
||||
|
||||
mulss xmm1, [ebp+%$lvolume]
|
||||
mulss xmm2, [ebp+%$rvolume]
|
||||
|
||||
addss xmm3, xmm1
|
||||
addss xmm4, xmm2
|
||||
|
||||
movss [edi], xmm3
|
||||
movss [edi+4], xmm4
|
||||
|
||||
add edi, 8
|
||||
add esi, 8
|
||||
|
||||
dec ecx
|
||||
jnz near mixloopStoSrolled
|
||||
|
||||
mixStoSdone:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
endproc
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_MixMonoTo5_1_SIMD(float *inbuffer, float *outbuffer, unsigned int length, float *volume0to3, float *volume4to1, float *volume2to5);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_MixMonoTo5_1_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$volume0to3 arg
|
||||
%$volume4to1 arg
|
||||
%$volume2to5 arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [l00 ][l10 ][l20 ][l30 ]
|
||||
; xmm1 = [l40 ][l50 ][l00 ][l10 ]
|
||||
; xmm2 = [l20 ][l30 ][l40 ][l50 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
|
||||
mov eax, [ebp+%$volume0to3]
|
||||
movups xmm0, [eax]
|
||||
mov eax, [ebp+%$volume4to1]
|
||||
movups xmm1, [eax]
|
||||
mov eax, [ebp+%$volume2to5]
|
||||
movups xmm2, [eax]
|
||||
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near mixloopMto51rolledstart
|
||||
|
||||
mixloopMto51unrolled:
|
||||
|
||||
movss xmm3, [esi + 0]
|
||||
movlps xmm4, [esi + 0]
|
||||
shufps xmm3, xmm3, 0
|
||||
shufps xmm4, xmm4, 50h
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi]
|
||||
addps xmm4, [edi + 16]
|
||||
movaps [edi], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
movss xmm3, [esi + 4]
|
||||
movss xmm4, [esi + 8]
|
||||
shufps xmm3, xmm3, 0
|
||||
shufps xmm4, xmm4, 0
|
||||
mulps xmm3, xmm2
|
||||
mulps xmm4, xmm0
|
||||
addps xmm3, [edi + 32]
|
||||
addps xmm4, [edi + 48]
|
||||
movaps [edi+32], xmm3
|
||||
movaps [edi+48], xmm4
|
||||
|
||||
movlps xmm3, [esi + 8]
|
||||
movss xmm4, [esi + 12]
|
||||
shufps xmm3, xmm3, 50h
|
||||
shufps xmm4, xmm4, 0
|
||||
mulps xmm3, xmm1
|
||||
mulps xmm4, xmm2
|
||||
addps xmm3, [edi + 64]
|
||||
addps xmm4, [edi + 80]
|
||||
movaps [edi+64], xmm3
|
||||
movaps [edi+80], xmm4
|
||||
|
||||
add edi, 96
|
||||
add esi, 16
|
||||
dec ecx
|
||||
jnz near mixloopMto51unrolled
|
||||
|
||||
mixloopMto51rolledstart:
|
||||
|
||||
mov ecx, ebp
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mixMto51done
|
||||
|
||||
mixloopMto51rolled:
|
||||
|
||||
movss xmm3, [esi + 0]
|
||||
shufps xmm3, xmm3, 0
|
||||
movups xmm4, [edi]
|
||||
mulps xmm3, xmm0
|
||||
addps xmm4, xmm3
|
||||
movups [edi], xmm4
|
||||
|
||||
movlps xmm3, [esi + 0]
|
||||
shufps xmm3, xmm3, 50h
|
||||
movlps xmm4, [edi + 16]
|
||||
mulps xmm3, xmm1
|
||||
addps xmm4, xmm3
|
||||
movlps [edi + 16], xmm4
|
||||
|
||||
add edi, 24
|
||||
add esi, 4
|
||||
|
||||
dec ecx
|
||||
jnz near mixloopMto51rolled
|
||||
|
||||
mixMto51done:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
endproc
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_Mix5_1To5_1_SIMD(float *inbuffer, float *outbuffer, unsigned int length, float *volume0to3, float *volume4to1, float *volume2to5);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_Mix5_1To5_1_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$volume0to3 arg
|
||||
%$volume4to1 arg
|
||||
%$volume2to5 arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [l00 ][l10 ][l20 ][l30 ]
|
||||
; xmm1 = [l40 ][l50 ][l00 ][l10 ]
|
||||
; xmm2 = [l20 ][l30 ][l40 ][l50 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
|
||||
mov eax, [ebp+%$volume0to3]
|
||||
movups xmm0, [eax]
|
||||
mov eax, [ebp+%$volume4to1]
|
||||
movups xmm1, [eax]
|
||||
mov eax, [ebp+%$volume2to5]
|
||||
movups xmm2, [eax]
|
||||
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near mixloop51to51rolledstart
|
||||
|
||||
mixloop51to51unrolled:
|
||||
|
||||
movaps xmm3, [esi + 0]
|
||||
movaps xmm4, [esi + 16]
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 0]
|
||||
addps xmm4, [edi + 16]
|
||||
movaps [edi], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
movaps xmm3, [esi + 32]
|
||||
movaps xmm4, [esi + 48]
|
||||
mulps xmm3, xmm2
|
||||
mulps xmm4, xmm0
|
||||
addps xmm3, [edi + 32]
|
||||
addps xmm4, [edi + 48]
|
||||
movaps [edi+32], xmm3
|
||||
movaps [edi+48], xmm4
|
||||
|
||||
movaps xmm3, [esi + 64]
|
||||
movaps xmm4, [esi + 80]
|
||||
mulps xmm3, xmm1
|
||||
mulps xmm4, xmm2
|
||||
addps xmm3, [edi + 64]
|
||||
addps xmm4, [edi + 80]
|
||||
movaps [edi+64], xmm3
|
||||
movaps [edi+80], xmm4
|
||||
|
||||
add edi, 96
|
||||
add esi, 96
|
||||
dec ecx
|
||||
jnz near mixloop51to51unrolled
|
||||
|
||||
mixloop51to51rolledstart:
|
||||
|
||||
mov ecx, ebp
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mix51to51done
|
||||
|
||||
mixloop51to51rolled:
|
||||
|
||||
movups xmm3, [esi + 0]
|
||||
movups xmm4, [edi + 0]
|
||||
mulps xmm3, xmm0
|
||||
addps xmm4, xmm3
|
||||
movups [edi], xmm4
|
||||
|
||||
movlps xmm3, [esi + 16]
|
||||
movlps xmm4, [edi + 16]
|
||||
mulps xmm3, xmm1
|
||||
addps xmm4, xmm3
|
||||
movlps [edi+16], xmm4
|
||||
|
||||
add edi, 24
|
||||
add esi, 24
|
||||
|
||||
dec ecx
|
||||
jnz near mixloop51to51rolled
|
||||
|
||||
mix51to51done:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
endproc
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_MixMonoTo7_1_SIMD(float *inbuffer, float *outbuffer, unsigned int length, float *volume0to3, float *volume4to7);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_MixMonoTo7_1_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$volume0to3 arg
|
||||
%$volume4to7 arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [l00 ][l10 ][l20 ][l30 ]
|
||||
; xmm1 = [l40 ][l50 ][l00 ][l10 ]
|
||||
; xmm2 = [l20 ][l30 ][l40 ][l50 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
|
||||
mov eax, [ebp+%$volume0to3]
|
||||
movups xmm0, [eax]
|
||||
mov eax, [ebp+%$volume4to7]
|
||||
movups xmm1, [eax]
|
||||
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near mixloopMto71rolledstart
|
||||
|
||||
mixloopMto71unrolled:
|
||||
|
||||
movss xmm3, [esi + 0]
|
||||
shufps xmm3, xmm3, 0
|
||||
movaps xmm4, xmm3
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 0]
|
||||
addps xmm4, [edi + 16]
|
||||
movaps [edi+0], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
movss xmm3, [esi + 4]
|
||||
shufps xmm3, xmm3, 0
|
||||
movaps xmm4, xmm3
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 32]
|
||||
addps xmm4, [edi + 48]
|
||||
movaps [edi+32], xmm3
|
||||
movaps [edi+48], xmm4
|
||||
|
||||
movss xmm3, [esi + 8]
|
||||
shufps xmm3, xmm3, 0
|
||||
movaps xmm4, xmm3
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 64]
|
||||
addps xmm4, [edi + 80]
|
||||
movaps [edi+64], xmm3
|
||||
movaps [edi+80], xmm4
|
||||
|
||||
movss xmm3, [esi + 12]
|
||||
shufps xmm3, xmm3, 0
|
||||
movaps xmm4, xmm3
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 96]
|
||||
addps xmm4, [edi + 112]
|
||||
movaps [edi+96], xmm3
|
||||
movaps [edi+112], xmm4
|
||||
|
||||
add edi, 128
|
||||
add esi, 16
|
||||
dec ecx
|
||||
jnz near mixloopMto71unrolled
|
||||
|
||||
mixloopMto71rolledstart:
|
||||
|
||||
mov ecx, ebp
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mixMto71done
|
||||
|
||||
mixloopMto71rolled:
|
||||
|
||||
movss xmm3, [esi + 0]
|
||||
shufps xmm3, xmm3, 0
|
||||
movaps xmm4, xmm3
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 0]
|
||||
addps xmm4, [edi + 16]
|
||||
movaps [edi+0], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
add edi, 32
|
||||
add esi, 4
|
||||
|
||||
dec ecx
|
||||
jnz near mixloopMto71rolled
|
||||
|
||||
mixMto71done:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
endproc
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Connection_Mix7_1To7_1_SIMD(float *inbuffer, float *outbuffer, unsigned int length, float *volume0to3, float *volume4to7);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Connection_Mix7_1To7_1_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$volume0to3 arg
|
||||
%$volume4to7 arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [l00 ][l10 ][l20 ][l30 ]
|
||||
; xmm1 = [l40 ][l50 ][l00 ][l10 ]
|
||||
; xmm2 = [l20 ][l30 ][l40 ][l50 ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
mov ecx, edx
|
||||
|
||||
mov eax, [ebp+%$volume0to3]
|
||||
movups xmm0, [eax]
|
||||
mov eax, [ebp+%$volume4to7]
|
||||
movups xmm1, [eax]
|
||||
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near mixloop71to71rolledstart
|
||||
|
||||
mixloop71to71unrolled:
|
||||
|
||||
movaps xmm3, [esi + 0]
|
||||
movaps xmm4, [esi + 16]
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 0]
|
||||
addps xmm4, [edi + 16]
|
||||
movaps [edi], xmm3
|
||||
movaps [edi+16], xmm4
|
||||
|
||||
movaps xmm3, [esi + 32]
|
||||
movaps xmm4, [esi + 48]
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 32]
|
||||
addps xmm4, [edi + 48]
|
||||
movaps [edi+32], xmm3
|
||||
movaps [edi+48], xmm4
|
||||
|
||||
movaps xmm3, [esi + 64]
|
||||
movaps xmm4, [esi + 80]
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 64]
|
||||
addps xmm4, [edi + 80]
|
||||
movaps [edi+64], xmm3
|
||||
movaps [edi+80], xmm4
|
||||
|
||||
movaps xmm3, [esi + 96]
|
||||
movaps xmm4, [esi + 112]
|
||||
mulps xmm3, xmm0
|
||||
mulps xmm4, xmm1
|
||||
addps xmm3, [edi + 96]
|
||||
addps xmm4, [edi + 112]
|
||||
movaps [edi+96], xmm3
|
||||
movaps [edi+112], xmm4
|
||||
|
||||
add edi, 128
|
||||
add esi, 128
|
||||
dec ecx
|
||||
jnz near mixloop71to71unrolled
|
||||
|
||||
mixloop71to71rolledstart:
|
||||
|
||||
mov ecx, ebp
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz mix71to71done
|
||||
|
||||
mixloop71to71rolled:
|
||||
|
||||
movups xmm3, [esi + 0]
|
||||
movups xmm4, [edi + 0]
|
||||
mulps xmm3, xmm0
|
||||
addps xmm4, xmm3
|
||||
movups [edi], xmm4
|
||||
|
||||
movups xmm3, [esi + 16]
|
||||
movups xmm4, [edi + 16]
|
||||
mulps xmm3, xmm1
|
||||
addps xmm4, xmm3
|
||||
movups [edi+16], xmm4
|
||||
|
||||
add edi, 32
|
||||
add esi, 32
|
||||
|
||||
dec ecx
|
||||
jnz near mixloop71to71rolled
|
||||
|
||||
mix71to71done:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
endproc
|
||||
148
fmod/win32/src/fmod_dsp_convert_asm.s
Executable file
148
fmod/win32/src/fmod_dsp_convert_asm.s
Executable file
|
|
@ -0,0 +1,148 @@
|
|||
%include "./FMOD_static/win32/src/c32.mac"
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL UNINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .bss use32 align=32]
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL PREINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
section .text
|
||||
align 16
|
||||
|
||||
negones dd -32768.0, -32768.0, -32768.0, -32768.0
|
||||
ones dd 32767.0, 32767.0, 32767.0, 32767.0
|
||||
|
||||
; ==========================================================================================
|
||||
; CODE
|
||||
; ==========================================================================================
|
||||
|
||||
section .text
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Convert_FloatToPCM16(short *outbuffer, float *inbuffer, unsigned int length, int destchannelstep, int srcchannelstep, float volume);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Convert_FloatToPCM16
|
||||
|
||||
%$outbuffer arg
|
||||
%$inbuffer arg
|
||||
%$length arg
|
||||
%$destchannelstep arg
|
||||
%$srcchannelstep arg
|
||||
%$volume arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
; xmm0 = [ ][ ][ ][ ]
|
||||
; xmm1 = [ ][ ][ ][ ]
|
||||
; xmm2 = [ ][ ][ ][ ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
mov eax, [ebp+%$srcchannelstep]
|
||||
shl eax, 2
|
||||
mov ebx, [ebp+%$destchannelstep]
|
||||
shl ebx, 1
|
||||
|
||||
movss xmm4, [ebp+%$volume]
|
||||
shufps xmm4, xmm4, 0
|
||||
movaps xmm5, [negones]
|
||||
movaps xmm6, [ones]
|
||||
|
||||
%if 1
|
||||
mov ecx, [ebp+%$length]
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near convertf2int16rolledstart
|
||||
|
||||
convertf2int16unrolled:
|
||||
|
||||
movss xmm0, [esi]
|
||||
movss xmm1, [esi + eax]
|
||||
lea esi, [esi + eax * 2]
|
||||
movss xmm2, [esi]
|
||||
movss xmm3, [esi + eax]
|
||||
lea esi, [esi + eax * 2]
|
||||
|
||||
unpcklps xmm0, xmm1
|
||||
unpcklps xmm2, xmm3
|
||||
shufps xmm0, xmm2, 044h
|
||||
|
||||
mulps xmm0, xmm4 ; now from -1/+1 to -32768/+32767 (and may be outside of this range)
|
||||
|
||||
movhlps xmm1, xmm0
|
||||
|
||||
cvttps2pi mm0, xmm0
|
||||
cvttps2pi mm1, xmm1
|
||||
|
||||
packssdw mm0, mm0 ; clamps to -32768 to 32767
|
||||
packssdw mm1, mm1 ; clamps to -32768 to 32767
|
||||
|
||||
movd edx, mm0
|
||||
mov [edi + 0], dl
|
||||
mov [edi + 1], dh
|
||||
shr edx, 16
|
||||
mov [edi + ebx + 0], dl
|
||||
mov [edi + ebx + 1], dh
|
||||
lea edi, [edi + ebx * 2]
|
||||
|
||||
movd edx, mm1
|
||||
mov [edi + 0], dl
|
||||
mov [edi + 1], dh
|
||||
shr edx, 16
|
||||
mov [edi + ebx + 0], dl
|
||||
mov [edi + ebx + 1], dh
|
||||
lea edi, [edi + ebx * 2]
|
||||
|
||||
dec ecx
|
||||
jnz near convertf2int16unrolled
|
||||
|
||||
convertf2int16rolledstart:
|
||||
|
||||
mov ecx, [ebp+%$length]
|
||||
and ecx, 3
|
||||
%endif
|
||||
test ecx, ecx
|
||||
jz near convertf2int16done
|
||||
|
||||
convertf2int16rolled:
|
||||
|
||||
movss xmm0, [esi]
|
||||
mulps xmm0, xmm4 ; now from -1/+1 to -32768/+32767 (and may be outside of this range)
|
||||
cvttps2pi mm0, xmm0
|
||||
packssdw mm0, mm0 ; clamps to -32768 to 32767
|
||||
movd edx, mm0
|
||||
mov [edi + 0], dl
|
||||
mov [edi + 1], dh
|
||||
|
||||
add edi, ebx
|
||||
add esi, eax
|
||||
dec ecx
|
||||
jnz near convertf2int16rolled
|
||||
|
||||
convertf2int16done:
|
||||
|
||||
emms
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
endproc
|
||||
|
||||
612
fmod/win32/src/fmod_dsp_distortion.cpp
Executable file
612
fmod/win32/src/fmod_dsp_distortion.cpp
Executable file
|
|
@ -0,0 +1,612 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_DISTORTION
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_dspi.h"
|
||||
#include "fmod_dsp_distortion.h"
|
||||
#include "fmod_systemi.h"
|
||||
#include "fmod_os_misc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
FMOD_DSP_DESCRIPTION_EX dspdistortion;
|
||||
|
||||
#ifdef PLUGIN_EXPORTS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
FMODGetDSPDescription is mandantory for every fmod plugin. This is the symbol the registerplugin function searches for.
|
||||
Must be declared with F_API to make it export as stdcall.
|
||||
*/
|
||||
F_DECLSPEC F_DLLEXPORT FMOD_DSP_DESCRIPTION_EX * F_API FMODGetDSPDescriptionEx()
|
||||
{
|
||||
return DSPDistortion::getDescriptionEx();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PLUGIN_EXPORTS */
|
||||
|
||||
FMOD_DSP_PARAMETERDESC dspdistortion_param[1] =
|
||||
{
|
||||
{ 0.0f, 1.0f, 0.5, "Level", "", "Distortion value. 0.0 to 1.0. Default = 0.5." },
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void FMOD_DSP_Distortion_SIMD(float * inbuffer, float * outbuffer, unsigned int length, int inchannels, int outchannels, float k);
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_DSP_DESCRIPTION_EX *DSPDistortion::getDescriptionEx()
|
||||
{
|
||||
FMOD_memset(&dspdistortion, 0, sizeof(FMOD_DSP_DESCRIPTION_EX));
|
||||
|
||||
FMOD_strcpy(dspdistortion.name, "FMOD Distortion");
|
||||
dspdistortion.version = 0x00010100;
|
||||
dspdistortion.create = DSPDistortion::createCallback;
|
||||
dspdistortion.release = DSPDistortion::releaseCallback;
|
||||
dspdistortion.reset = DSPDistortion::resetCallback;
|
||||
dspdistortion.read = DSPDistortion::readCallback;
|
||||
|
||||
dspdistortion.numparameters = sizeof(dspdistortion_param) / sizeof(dspdistortion_param[0]);
|
||||
dspdistortion.paramdesc = dspdistortion_param;
|
||||
dspdistortion.setparameter = DSPDistortion::setParameterCallback;
|
||||
dspdistortion.getparameter = DSPDistortion::getParameterCallback;
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
dspdistortion.getmemoryused = &DSPDistortion::getMemoryUsedCallback;
|
||||
#endif
|
||||
|
||||
dspdistortion.mType = FMOD_DSP_TYPE_DISTORTION;
|
||||
dspdistortion.mCategory = FMOD_DSP_CATEGORY_FILTER;
|
||||
dspdistortion.mSize = sizeof(DSPDistortion);
|
||||
|
||||
return &dspdistortion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::createInternal()
|
||||
{
|
||||
int count;
|
||||
|
||||
init();
|
||||
|
||||
mSupportsSIMD = FMOD_OS_SupportsSIMD();
|
||||
|
||||
for (count = 0; count < mDescription.numparameters; count++)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = setParameter(count, mDescription.paramdesc[count].defaultval);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::releaseInternal()
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::resetInternal()
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::readInternal(float * inbuffer, float * outbuffer, unsigned int length, int inchannels, int outchannels)
|
||||
{
|
||||
float k;
|
||||
float level = mLevel;
|
||||
|
||||
if (!inbuffer)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
if (!(speakermask & ((1 << inchannels)-1)))
|
||||
{
|
||||
FMOD_memcpy(outbuffer, inbuffer, sizeof(float)*length*inchannels);
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
if (level < 1.0f)
|
||||
{
|
||||
k = 2.0f * level / (1.0f - level);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 2.0f * 0.9999f / (1.0f - 0.9999f);
|
||||
}
|
||||
|
||||
if (mSupportsSIMD)
|
||||
{
|
||||
FMOD_DSP_Distortion_SIMD(inbuffer, outbuffer, length, inchannels, outchannels, k);
|
||||
if (!((speakermask & ((1<<inchannels)-1)) == ((1<<inchannels)-1)))
|
||||
{
|
||||
unsigned int len;
|
||||
int count, inc;
|
||||
|
||||
for (count = 0; count < inchannels; count++)
|
||||
{
|
||||
float *in = inbuffer + count;
|
||||
float *out = outbuffer + count;
|
||||
len = length >> 3;
|
||||
inc = inchannels << 3;
|
||||
int offset1, offset2, offset3, offset4, offset5, offset6, offset7;
|
||||
offset1 = inchannels;
|
||||
offset2 = inchannels * 2;
|
||||
offset3 = inchannels * 3;
|
||||
offset4 = inchannels * 4;
|
||||
offset5 = inchannels * 5;
|
||||
offset6 = inchannels * 6;
|
||||
offset7 = inchannels * 7;
|
||||
|
||||
if (!((1 << count) & speakermask))
|
||||
{
|
||||
while (len)
|
||||
{
|
||||
out[0] = in[0];
|
||||
out[offset1] = in[offset1];
|
||||
out[offset2] = in[offset2];
|
||||
out[offset3] = in[offset3];
|
||||
out[offset4] = in[offset4];
|
||||
out[offset5] = in[offset5];
|
||||
out[offset6] = in[offset6];
|
||||
out[offset7] = in[offset7];
|
||||
in += inc;
|
||||
out += inc;
|
||||
len--;
|
||||
}
|
||||
|
||||
len = length & 7;
|
||||
|
||||
while (len)
|
||||
{
|
||||
outbuffer[0] = inbuffer[0];
|
||||
inbuffer += inchannels;
|
||||
outbuffer += inchannels;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int len;
|
||||
int count, inc;
|
||||
int offset1, offset2, offset3, offset4, offset5, offset6, offset7;
|
||||
inc = inchannels << 3;
|
||||
offset1 = inchannels;
|
||||
offset2 = inchannels * 2;
|
||||
offset3 = inchannels * 3;
|
||||
offset4 = inchannels * 4;
|
||||
offset5 = inchannels * 5;
|
||||
offset6 = inchannels * 6;
|
||||
offset7 = inchannels * 7;
|
||||
|
||||
for (count = 0; count < inchannels; count++)
|
||||
{
|
||||
float *in = inbuffer + count;
|
||||
float *out = outbuffer + count;
|
||||
len = length >> 3;
|
||||
|
||||
if (!((1 << count) & speakermask))
|
||||
{
|
||||
while (len)
|
||||
{
|
||||
out[0] = in[0];
|
||||
out[offset1] = in[offset1];
|
||||
out[offset2] = in[offset2];
|
||||
out[offset3] = in[offset3];
|
||||
out[offset4] = in[offset4];
|
||||
out[offset5] = in[offset5];
|
||||
out[offset6] = in[offset6];
|
||||
out[offset7] = in[offset7];
|
||||
in += inc;
|
||||
out += inc;
|
||||
len--;
|
||||
}
|
||||
|
||||
len = (length * inchannels) & 7;
|
||||
|
||||
while (len)
|
||||
{
|
||||
outbuffer[0] = inbuffer[0];
|
||||
inbuffer+=inchannels;
|
||||
outbuffer+=inchannels;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float kplus1 = 1.0f + k;
|
||||
|
||||
while (len)
|
||||
{
|
||||
out[0] = kplus1 * in[0] / (1.0f + k * FMOD_FABS(in[0]));
|
||||
out[offset1] = kplus1 * in[offset1] / (1.0f + k * FMOD_FABS(in[offset1]));
|
||||
out[offset2] = kplus1 * in[offset2] / (1.0f + k * FMOD_FABS(in[offset2]));
|
||||
out[offset3] = kplus1 * in[offset3] / (1.0f + k * FMOD_FABS(in[offset3]));
|
||||
out[offset4] = kplus1 * in[offset4] / (1.0f + k * FMOD_FABS(in[offset4]));
|
||||
out[offset5] = kplus1 * in[offset5] / (1.0f + k * FMOD_FABS(in[offset5]));
|
||||
out[offset6] = kplus1 * in[offset6] / (1.0f + k * FMOD_FABS(in[offset6]));
|
||||
out[offset7] = kplus1 * in[offset7] / (1.0f + k * FMOD_FABS(in[offset7]));
|
||||
in += inc;
|
||||
out += inc;
|
||||
len--;
|
||||
}
|
||||
|
||||
len = (length * inchannels) & 7;
|
||||
|
||||
while (len)
|
||||
{
|
||||
outbuffer[0] = kplus1 * inbuffer[0] / (1.0f + k * FMOD_FABS(inbuffer[0]));
|
||||
inbuffer+=inchannels;
|
||||
outbuffer+=inchannels;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::setParameterInternal(int index, float value)
|
||||
{
|
||||
mLevel = value;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPDistortion::getParameterInternal(int index, float *value, char *valuestr)
|
||||
{
|
||||
*value = mLevel;
|
||||
sprintf(valuestr, "%.02f", mLevel);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
|
||||
FMOD_RESULT DSPDistortion::getMemoryUsedImpl(MemoryTracker *tracker)
|
||||
{
|
||||
// Size of this class is already accounted for (via description.mSize). Just add extra allocated memory here.
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================================================
|
||||
|
||||
CALLBACK INTERFACE
|
||||
|
||||
==============================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::createCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->createInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::releaseCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->releaseInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::resetCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->resetInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::readCallback(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->readInternal(inbuffer, outbuffer, length, inchannels, outchannels);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::setParameterCallback(FMOD_DSP_STATE *dsp, int index, float value)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->setParameterInternal(index, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::getParameterCallback(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->getParameterInternal(index, value, valuestr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPDistortion::getMemoryUsedCallback(FMOD_DSP_STATE *dsp, MemoryTracker *tracker)
|
||||
{
|
||||
DSPDistortion *distortion = (DSPDistortion *)dsp;
|
||||
|
||||
return distortion->DSPDistortion::getMemoryUsed(tracker);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
128
fmod/win32/src/fmod_dsp_distortion_asm.s
Executable file
128
fmod/win32/src/fmod_dsp_distortion_asm.s
Executable file
|
|
@ -0,0 +1,128 @@
|
|||
%include "./FMOD_static/win32/src/c32.mac"
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL UNINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .data use32 align=32]
|
||||
|
||||
distortion_ones dd 1.0,1.0,1.0,1.0
|
||||
distortion_fabsmask dd 7FFFFFFFh, 7FFFFFFFh, 7FFFFFFFh, 7FFFFFFFh
|
||||
|
||||
; ==========================================================================================
|
||||
; CODE
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .text use32 align=32]
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_DSP_Distortion_SIMD(float * inbuffer, float * outbuffer, unsigned int length, int inchannels, int outchannels, float k);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_DSP_Distortion_SIMD
|
||||
|
||||
%$inbuffer arg
|
||||
%$outbuffer arg
|
||||
%$length arg
|
||||
%$inchannels arg
|
||||
%$outchannels arg
|
||||
%$k arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [ebp+%$inbuffer]
|
||||
mov edi, [ebp+%$outbuffer]
|
||||
|
||||
; xmm0 = [0x7fffffff][0x7fffffff][0x7fffffff][0x7fffffff]
|
||||
; xmm1 = [k ][k ][k ][k ]
|
||||
; xmm2 = [k+1 ][k+1 ][k+1 ][k+1 ]
|
||||
; xmm3 =
|
||||
; xmm4 =
|
||||
; xmm5 = [1.0f ][1.0f ][1.0f ][1.0f ]
|
||||
; xmm6 =
|
||||
; xmm7 =
|
||||
|
||||
movaps xmm0, [distortion_fabsmask]
|
||||
movss xmm1, [ebp+%$k]
|
||||
shufps xmm1, xmm1, 0x00
|
||||
movaps xmm2, xmm1
|
||||
movaps xmm5, [distortion_ones]
|
||||
addps xmm2, xmm5
|
||||
|
||||
mov edx, [ebp+%$length]
|
||||
imul edx, [ebp+%$inchannels]
|
||||
mov ecx, edx
|
||||
shr ecx, 3
|
||||
test ecx, ecx
|
||||
jz distortionlooprolledstart
|
||||
|
||||
distortionloopunrolled:
|
||||
|
||||
movups xmm3, [esi]
|
||||
movups xmm4, xmm3
|
||||
andps xmm3, xmm0
|
||||
mulps xmm3, xmm1
|
||||
addps xmm3, xmm5
|
||||
rcpps xmm3, xmm3 ; <--- this is the reciprical calc.
|
||||
mulps xmm4, xmm2 ; |
|
||||
; divps xmm4, xmm3 ; |
|
||||
mulps xmm4, xmm3 ; reciprical multiply instead of a div. Only 12bit accuracy but good enough for here. much faster.
|
||||
movups [edi], xmm4
|
||||
|
||||
movups xmm6, [esi+16]
|
||||
movups xmm7, xmm6
|
||||
andps xmm6, xmm0
|
||||
mulps xmm6, xmm1
|
||||
addps xmm6, xmm5
|
||||
rcpps xmm6, xmm6 ; <--- this is the reciprical calc.
|
||||
mulps xmm7, xmm2 ; |
|
||||
; divps xmm7, xmm6 ; |
|
||||
mulps xmm7, xmm6 ; reciprical multiply instead of a div. Only 12bit accuracy but good enough for here. much faster.
|
||||
movups [edi+16], xmm7
|
||||
|
||||
add edi, 32
|
||||
add esi, 32
|
||||
dec ecx
|
||||
jnz near distortionloopunrolled
|
||||
|
||||
distortionlooprolledstart:
|
||||
|
||||
xorps xmm3, xmm3
|
||||
|
||||
mov ecx, edx
|
||||
and ecx, 7
|
||||
test ecx, ecx
|
||||
jz distortiondone
|
||||
|
||||
distortionlooprolled:
|
||||
|
||||
movss xmm3, [esi]
|
||||
movss xmm4, xmm3
|
||||
andps xmm3, xmm0
|
||||
mulss xmm3, xmm1
|
||||
addss xmm3, xmm5
|
||||
rcpss xmm3, xmm3 ; <--- this is the reciprical calc.
|
||||
mulss xmm4, xmm2 ; |
|
||||
; divss xmm4, xmm3 ; |
|
||||
mulss xmm4, xmm3 ; reciprical multiply instead of a div. Only 12bit accuracy but good enough for here. much faster.
|
||||
movss [edi], xmm4
|
||||
|
||||
add edi, 4
|
||||
add esi, 4
|
||||
|
||||
dec ecx
|
||||
jnz near distortionlooprolled
|
||||
|
||||
distortiondone:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
endproc
|
||||
621
fmod/win32/src/fmod_dsp_resampler_linear.cpp
Executable file
621
fmod/win32/src/fmod_dsp_resampler_linear.cpp
Executable file
|
|
@ -0,0 +1,621 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#include "fmod_dsp_resampler_linear.h"
|
||||
#include "fmod_os_misc.h"
|
||||
|
||||
#define OO4GIG (1.0f / 4294967296.0f)
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void FMOD_Resampler_Linear_PCM16_Mono(float *out, int outlength, void *src, FMOD_UINT64P *position, FMOD_SINT64P *speed);
|
||||
void FMOD_Resampler_Linear_PCM16_Stereo(float *out, int outlength, void *src, FMOD_UINT64P *position, FMOD_SINT64P *speed);
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64, Linux, Macintosh, XBox, PlayStation 2, GameCube
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
void FMOD_Resampler_Linear(float *out, int outlength, void *src, FMOD_SOUND_FORMAT srcformat, FMOD_UINT64P *position, FMOD_SINT64P *speed, int channels)
|
||||
{
|
||||
float scale = 1.0f;
|
||||
bool supportssimd;
|
||||
|
||||
supportssimd = FMOD_OS_SupportsSIMD();
|
||||
|
||||
switch (srcformat)
|
||||
{
|
||||
/*
|
||||
8 BIT
|
||||
*/
|
||||
case FMOD_SOUND_FORMAT_PCM8:
|
||||
{
|
||||
signed char *inptr = (signed char *)src;
|
||||
|
||||
scale /= (float)(1<<7);
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
float f;
|
||||
float a, b, r1,r2,r3,r4;
|
||||
int len;
|
||||
|
||||
len = outlength >> 2;
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r2 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r3 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r4 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = r1;
|
||||
out[1] = r2;
|
||||
out[2] = r3;
|
||||
out[3] = r4;
|
||||
len--;
|
||||
out+=4;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
|
||||
*out++ = r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
float f;
|
||||
float l_a,l_b, l_r1,l_r2,l_r3,l_r4;
|
||||
float r_a,r_b, r_r1,r_r2,r_r3,r_r4;
|
||||
int len;
|
||||
|
||||
len = outlength >> 2;
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r1 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r1 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r2 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r2 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r3 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r3 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r4 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r4 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = l_r1;
|
||||
out[1] = r_r1;
|
||||
out[2] = l_r2;
|
||||
out[3] = r_r2;
|
||||
out[4] = l_r3;
|
||||
out[5] = r_r3;
|
||||
out[6] = l_r4;
|
||||
out[7] = r_r4;
|
||||
|
||||
len--;
|
||||
out+=8;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r1 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r1 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
|
||||
*out++ = l_r1;
|
||||
*out++ = r_r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
float p0 = (float)inptr[((position->mHi + 0) * channels) + count] * scale;
|
||||
float p1 = (float)inptr[((position->mHi + 1) * channels) + count] * scale;
|
||||
float r;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
16 BIT
|
||||
*/
|
||||
case FMOD_SOUND_FORMAT_PCM16:
|
||||
{
|
||||
signed short *inptr = (signed short *)src;
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
if (supportssimd)
|
||||
{
|
||||
FMOD_Resampler_Linear_PCM16_Mono(out, outlength, src, position, speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
float f;
|
||||
float a, b, r1,r2,r3,r4;
|
||||
int len;
|
||||
|
||||
scale /= (float)(1<<15);
|
||||
len = outlength >> 2;
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r2 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r3 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r4 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = r1;
|
||||
out[1] = r2;
|
||||
out[2] = r3;
|
||||
out[3] = r4;
|
||||
len--;
|
||||
out+=4;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
|
||||
*out++ = r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (channels == 2)
|
||||
{
|
||||
if (supportssimd)
|
||||
{
|
||||
FMOD_Resampler_Linear_PCM16_Stereo(out, outlength, src, position, speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
float f;
|
||||
float l_a,l_b, l_r1,l_r2,l_r3,l_r4;
|
||||
float r_a,r_b, r_r1,r_r2,r_r3,r_r4;
|
||||
int len;
|
||||
|
||||
scale /= (float)(1<<15);
|
||||
len = outlength >> 2;
|
||||
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r1 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r1 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r2 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r2 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r3 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r3 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r4 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r4 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = l_r1;
|
||||
out[1] = r_r1;
|
||||
out[2] = l_r2;
|
||||
out[3] = r_r2;
|
||||
out[4] = l_r3;
|
||||
out[5] = r_r3;
|
||||
out[6] = l_r4;
|
||||
out[7] = r_r4;
|
||||
len--;
|
||||
out+=8;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
l_a = (float)inptr[position->mHi * 2 + 0] * scale;
|
||||
l_b = (float)inptr[position->mHi * 2 + 2] * scale;
|
||||
r_a = (float)inptr[position->mHi * 2 + 1] * scale;
|
||||
r_b = (float)inptr[position->mHi * 2 + 3] * scale;
|
||||
l_r1 = (l_a * (1.0f - f)) + (l_b * f);
|
||||
r_r1 = (r_a * (1.0f - f)) + (r_b * f);
|
||||
|
||||
out[0] = l_r1;
|
||||
out[1] = r_r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
out+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scale /= (float)(1<<15);
|
||||
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
float p0 = (float)inptr[((position->mHi + 0) * channels) + count] * scale;
|
||||
float p1 = (float)inptr[((position->mHi + 1) * channels) + count] * scale;
|
||||
float r;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
24 BIT
|
||||
*/
|
||||
case FMOD_SOUND_FORMAT_PCM24:
|
||||
{
|
||||
FMOD_INT24 *inptr = (FMOD_INT24 *)src;
|
||||
|
||||
scale /= (float)(1<<23);
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float r;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
FMOD_INT24 *s0 = &inptr[position->mHi + 0];
|
||||
FMOD_INT24 *s1 = &inptr[position->mHi + 1];
|
||||
float p0 = (float)((int)(((unsigned int)s0->val[0] << 8) | ((unsigned int)s0->val[1] << 16) | ((unsigned int)s0->val[2] << 24)) >> 8) * scale;
|
||||
float p1 = (float)((int)(((unsigned int)s1->val[0] << 8) | ((unsigned int)s1->val[1] << 16) | ((unsigned int)s1->val[2] << 24)) >> 8) * scale;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float r;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
FMOD_INT24 *s0 = &inptr[((position->mHi + 0) * channels) + count];
|
||||
FMOD_INT24 *s1 = &inptr[((position->mHi + 1) * channels) + count];
|
||||
float p0 = (float)((int)(((unsigned int)s0->val[0] << 8) | ((unsigned int)s0->val[1] << 16) | ((unsigned int)s0->val[2] << 24)) >> 8) * scale;
|
||||
float p1 = (float)((int)(((unsigned int)s1->val[0] << 8) | ((unsigned int)s1->val[1] << 16) | ((unsigned int)s1->val[2] << 24)) >> 8) * scale;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
32 BIT
|
||||
*/
|
||||
case FMOD_SOUND_FORMAT_PCM32:
|
||||
{
|
||||
signed int *inptr = (signed int *)src;
|
||||
|
||||
scale /= (float)(1<<31);
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
float f;
|
||||
float a, b, r1,r2,r3,r4;
|
||||
int len;
|
||||
|
||||
len = outlength >> 2;
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r2 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r3 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r4 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = r1;
|
||||
out[1] = r2;
|
||||
out[2] = r3;
|
||||
out[3] = r4;
|
||||
len--;
|
||||
out+=4;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
a = (float)inptr[position->mHi + 0] * scale;
|
||||
b = (float)inptr[position->mHi + 1] * scale;
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
|
||||
*out++ = r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
float p0 = (float)inptr[((position->mHi + 0) * channels) + count] * scale;
|
||||
float p1 = (float)inptr[((position->mHi + 1) * channels) + count] * scale;
|
||||
float r;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
FLOATING POINT.
|
||||
*/
|
||||
case FMOD_SOUND_FORMAT_PCMFLOAT:
|
||||
{
|
||||
float *inptr = (float *)src;
|
||||
|
||||
if (channels == 1)
|
||||
{
|
||||
float f;
|
||||
float a, b, r1,r2,r3,r4;
|
||||
int len;
|
||||
|
||||
len = outlength >> 2;
|
||||
while (len)
|
||||
{
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = inptr[position->mHi + 0];
|
||||
b = inptr[position->mHi + 1];
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = inptr[position->mHi + 0];
|
||||
b = inptr[position->mHi + 1];
|
||||
r2 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = inptr[position->mHi + 0];
|
||||
b = inptr[position->mHi + 1];
|
||||
r3 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
f = (float)position->mLo * OO4GIG;
|
||||
a = inptr[position->mHi + 0];
|
||||
b = inptr[position->mHi + 1];
|
||||
r4 = (a * (1.0f - f)) + (b * f);
|
||||
position->mValue += speed->mValue;
|
||||
|
||||
out[0] = r1;
|
||||
out[1] = r2;
|
||||
out[2] = r3;
|
||||
out[3] = r4;
|
||||
len--;
|
||||
out+=4;
|
||||
}
|
||||
|
||||
len = outlength & 3;
|
||||
while (len)
|
||||
{
|
||||
f = position->mLo * OO4GIG;
|
||||
a = inptr[position->mHi + 0];
|
||||
b = inptr[position->mHi + 1];
|
||||
r1 = (a * (1.0f - f)) + (b * f);
|
||||
|
||||
*out++ = r1;
|
||||
|
||||
position->mValue += speed->mValue;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (outlength)
|
||||
{
|
||||
int count;
|
||||
float f = position->mLo * OO4GIG;
|
||||
|
||||
for (count = 0; count < channels; count++)
|
||||
{
|
||||
float p0 = inptr[((position->mHi + 0) * channels) + count];
|
||||
float p1 = inptr[((position->mHi + 1) * channels) + count];
|
||||
float r;
|
||||
|
||||
r = (p0 * (1.0f - f)) + (p1 * f);
|
||||
*out++ = r;
|
||||
}
|
||||
position->mValue += speed->mValue;
|
||||
outlength--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
440
fmod/win32/src/fmod_dsp_resampler_linear_asm.s
Executable file
440
fmod/win32/src/fmod_dsp_resampler_linear_asm.s
Executable file
|
|
@ -0,0 +1,440 @@
|
|||
%include "./FMOD_static/win32/src/c32.mac"
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL UNINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
section .bss
|
||||
align 16
|
||||
|
||||
%define samples esp+0
|
||||
%define samples_2 esp+10h
|
||||
%define samplesplus1 esp+20h
|
||||
%define samplesplus1_2 esp+30h
|
||||
%define fracs esp+40h
|
||||
%define fracs_2 esp+50h
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL PREINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
section .text
|
||||
align 16
|
||||
|
||||
ones_over_32768 dd 0.000030517578125, 0.000030517578125, 0.000030517578125, 0.000030517578125
|
||||
ones_over_2gig dd 0.0000000004656612873077392578125, 0.0000000004656612873077392578125, 0.0000000004656612873077392578125, 0.0000000004656612873077392578125
|
||||
ones dd 1.0, 1.0, 1.0, 1.0
|
||||
|
||||
; ==========================================================================================
|
||||
; CODE
|
||||
; ==========================================================================================
|
||||
|
||||
section .text
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_Resampler_Linear_PCM16_Mono(float *out, int outlength, void *src, FMOD_UINT64P *position, FMOD_SINT64P *speed);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_Resampler_Linear_PCM16_Mono
|
||||
|
||||
%$out arg
|
||||
%$outlength arg
|
||||
%$src arg
|
||||
%$position arg
|
||||
%$speed arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov eax, [ebp + %$position]
|
||||
mov eax, [eax]
|
||||
|
||||
mov esi, [ebp + %$src]
|
||||
shr esi, 1
|
||||
mov ebx, [ebp + %$position]
|
||||
add esi, [ebx + 4] ; esi is now addr / 2 + offset. when accessing we use [esi*2]
|
||||
|
||||
mov edx, [ebp + %$speed]
|
||||
mov edx, [edx + 4]
|
||||
mov ebx, [ebp + %$speed]
|
||||
mov ebx, [ebx]
|
||||
|
||||
mov edi, [ebp + %$out]
|
||||
mov ecx, [ebp + %$outlength]
|
||||
|
||||
; eax = poslo
|
||||
; ebx = speedlo
|
||||
; ecx = count
|
||||
; edx = speedhi
|
||||
; esi = src + poshi
|
||||
; edi = dest
|
||||
|
||||
; xmm0 = [ ][ ][ ][ ]
|
||||
; xmm1 = [ ][ ][ ][ ]
|
||||
; xmm2 = [ ][ ][ ][ ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
push ebp
|
||||
sub esp, 60h
|
||||
|
||||
xorps xmm0, xmm0
|
||||
movups [samples], xmm0
|
||||
movups [samples_2], xmm0
|
||||
movups [samplesplus1], xmm0
|
||||
movups [samplesplus1_2], xmm0
|
||||
movups [fracs], xmm0
|
||||
movups [fracs_2], xmm0
|
||||
|
||||
%if 1
|
||||
shr ecx, 2
|
||||
test ecx, ecx
|
||||
jz near resample16Mrolledstart
|
||||
|
||||
resample16Munrolled:
|
||||
|
||||
movsx ebp, word [esi*2]
|
||||
mov [samples + 0], ebp ; [ 1a][ ][ ][ ]
|
||||
movsx ebp, word [esi*2+2]
|
||||
mov [samplesplus1 + 0], ebp ; [ 1b][ ][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs + 0], ebp ; [ 1f][ ][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
movsx ebp, word [esi*2]
|
||||
mov [samples_2 + 0], ebp ; [ 2a][ ][ ][ ]
|
||||
movsx ebp, word [esi*2+2]
|
||||
mov [samplesplus1_2 + 0], ebp ; [ 2b][ ][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs_2 + 0], ebp ; [ 2f][ ][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
movsx ebp, word [esi*2]
|
||||
mov [samples + 4], ebp ; [ 1a][ 3a][ ][ ]
|
||||
movsx ebp, word [esi*2+2]
|
||||
mov [samplesplus1 + 4], ebp ; [ 1b][ 3b][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs + 4], ebp ; [ 1f][ 3f][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
movsx ebp, word [esi*2]
|
||||
mov [samples_2 + 4], ebp ; [ 2a][ 4a][ ][ ]
|
||||
movsx ebp, word [esi*2+2]
|
||||
mov [samplesplus1_2 + 4], ebp ; [ 2b][ 4b][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs_2 + 4], ebp ; [ 2f][ 4f][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
cvtpi2ps xmm0, [samples]
|
||||
cvtpi2ps xmm1, [samples_2]
|
||||
cvtpi2ps xmm2, [samplesplus1]
|
||||
cvtpi2ps xmm3, [samplesplus1_2]
|
||||
cvtpi2ps xmm4, [fracs]
|
||||
cvtpi2ps xmm5, [fracs_2]
|
||||
|
||||
unpcklps xmm0, xmm1 ; [ 1a][ 2a][ 3a][ 4a]
|
||||
unpcklps xmm2, xmm3 ; [ 1b][ 2b][ 3b][ 4b]
|
||||
unpcklps xmm4, xmm5 ; [ 1f][ 2f][ 3f][ 4f]
|
||||
|
||||
mulps xmm0, [ones_over_32768]
|
||||
mulps xmm2, [ones_over_32768]
|
||||
mulps xmm4, [ones_over_2gig]
|
||||
|
||||
movaps xmm6, [ones]
|
||||
subps xmm6, xmm4 ; [ 1.0-1f][ 1.0-2f][ 1.0-3f][ 1.0-4f]
|
||||
|
||||
mulps xmm2, xmm4 ;
|
||||
mulps xmm0, xmm6 ; [1a * 1.0-1f][2a *1.0-1f][3a *1.0-3f][4a * 1.0-4f]
|
||||
addps xmm0, xmm2
|
||||
movups [edi], xmm0
|
||||
|
||||
add edi, 16
|
||||
dec ecx
|
||||
jnz near resample16Munrolled
|
||||
|
||||
resample16Mrolledstart:
|
||||
|
||||
add esp, 60h
|
||||
pop ebp
|
||||
mov ecx, [ebp+%$outlength]
|
||||
push ebp
|
||||
sub esp, 60h
|
||||
and ecx, 3
|
||||
%endif
|
||||
xorps xmm0, xmm0
|
||||
xorps xmm2, xmm2
|
||||
xorps xmm4, xmm4
|
||||
test ecx, ecx
|
||||
jz near resample16Mdone
|
||||
|
||||
resample16Mrolled:
|
||||
|
||||
movsx ebp, word [esi*2]
|
||||
mov [samples + 0], ebp ; [ 1a][ ][ ][ ]
|
||||
movsx ebp, word [esi*2+2]
|
||||
mov [samplesplus1 + 0], ebp ; [ 1b][ ][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs + 0], ebp ; [ 1f][ ][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
cvtsi2ss xmm0, [samples]
|
||||
cvtsi2ss xmm2, [samplesplus1]
|
||||
cvtsi2ss xmm4, [fracs]
|
||||
|
||||
mulss xmm0, [ones_over_32768]
|
||||
mulss xmm2, [ones_over_32768]
|
||||
mulss xmm4, [ones_over_2gig]
|
||||
|
||||
movss xmm6, [ones]
|
||||
subss xmm6, xmm4 ; [ 1.0-1f][ 1.0-2f][ 1.0-3f][ 1.0-4f]
|
||||
|
||||
mulss xmm2, xmm4 ;
|
||||
mulss xmm0, xmm6 ; [1a * 1.0-1f][2a *1.0-1f][3a *1.0-3f][4a * 1.0-4f]
|
||||
addss xmm0, xmm2
|
||||
movss [edi], xmm0
|
||||
|
||||
add edi, 4
|
||||
dec ecx
|
||||
jnz near resample16Mrolled
|
||||
|
||||
resample16Mdone:
|
||||
add esp, 60h
|
||||
pop ebp
|
||||
|
||||
; restore position
|
||||
mov ecx, [ebp + %$position]
|
||||
mov [ecx + 0], eax
|
||||
|
||||
mov eax, [ebp + %$src]
|
||||
shr eax, 1
|
||||
sub esi, eax
|
||||
mov ecx, [ebp + %$position]
|
||||
mov [ecx + 4], esi
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
endproc
|
||||
|
||||
|
||||
; =================================================================================================================================
|
||||
; void FMOD_Resampler_Linear_PCM16_Stereo(float *out, int outlength, void *src, FMOD_UINT64P *position, FMOD_SINT64P *speed);
|
||||
; =================================================================================================================================
|
||||
proc FMOD_Resampler_Linear_PCM16_Stereo
|
||||
|
||||
%$out arg
|
||||
%$outlength arg
|
||||
%$src arg
|
||||
%$position arg
|
||||
%$speed arg
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov eax, [ebp + %$position]
|
||||
mov eax, [eax]
|
||||
|
||||
mov esi, [ebp + %$src]
|
||||
shr esi, 2
|
||||
mov ebx, [ebp + %$position]
|
||||
add esi, [ebx + 4] ; esi is now addr / 2 + offset. when accessing we use [esi*2]
|
||||
|
||||
mov edx, [ebp + %$speed]
|
||||
mov edx, [edx + 4]
|
||||
mov ebx, [ebp + %$speed]
|
||||
mov ebx, [ebx]
|
||||
|
||||
mov edi, [ebp + %$out]
|
||||
mov ecx, [ebp + %$outlength]
|
||||
|
||||
push ebp
|
||||
sub esp, 60h
|
||||
|
||||
; eax = poslo
|
||||
; ebx = speedlo
|
||||
; ecx = count
|
||||
; edx = speedhi
|
||||
; esi = src + poshi
|
||||
; edi = dest
|
||||
; ebp = temp
|
||||
|
||||
; xmm0 = [ ][ ][ ][ ]
|
||||
; xmm1 = [ ][ ][ ][ ]
|
||||
; xmm2 = [ ][ ][ ][ ]
|
||||
; xmm3 = [ ][ ][ ][ ]
|
||||
; xmm4 = [ ][ ][ ][ ]
|
||||
; xmm5 = [ ][ ][ ][ ]
|
||||
; xmm6 = [ ][ ][ ][ ]
|
||||
; xmm7 = [ ][ ][ ][ ]
|
||||
|
||||
xorps xmm0, xmm0
|
||||
movups [samples], xmm0
|
||||
movups [samples_2], xmm0
|
||||
movups [samplesplus1], xmm0
|
||||
movups [samplesplus1_2], xmm0
|
||||
movups [fracs], xmm0
|
||||
movups [fracs_2], xmm0
|
||||
|
||||
%if 1
|
||||
shr ecx, 1
|
||||
test ecx, ecx
|
||||
jz near resample16Srolledstart
|
||||
|
||||
resample16Sunrolled:
|
||||
|
||||
movsx ebp, word [esi*4+0]
|
||||
mov [samples + 0], ebp ; [ 1al][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+2]
|
||||
mov [samples + 4], ebp ; [ 1al][ 1ar][ ][ ]
|
||||
movsx ebp, word [esi*4+4]
|
||||
mov [samplesplus1 + 0], ebp ; [ 1bl][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+6]
|
||||
mov [samplesplus1 + 4], ebp ; [ 1bl][ 1br][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs + 0], ebp ; [ 1f][ ][ ][ ]
|
||||
mov [fracs + 4], ebp ; [ 1f][ 1f][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
movsx ebp, word [esi*4+0]
|
||||
mov [samples_2 + 0], ebp ; [ 2al][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+2]
|
||||
mov [samples_2 + 4], ebp ; [ 2al][ 2ar][ ][ ]
|
||||
movsx ebp, word [esi*4+4]
|
||||
mov [samplesplus1_2 + 0], ebp ; [ 2bl][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+6]
|
||||
mov [samplesplus1_2 + 4], ebp ; [ 2bl][ 2br][ ][ ]
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs_2 + 0], ebp ; [ 2f][ ][ ][ ]
|
||||
mov [fracs_2 + 4], ebp ; [ 2f][ 2f][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
cvtpi2ps xmm0, [samples]
|
||||
cvtpi2ps xmm1, [samples_2]
|
||||
cvtpi2ps xmm2, [samplesplus1]
|
||||
cvtpi2ps xmm3, [samplesplus1_2]
|
||||
cvtpi2ps xmm4, [fracs]
|
||||
cvtpi2ps xmm5, [fracs_2]
|
||||
|
||||
shufps xmm0, xmm1, 44h
|
||||
shufps xmm2, xmm3, 44h
|
||||
shufps xmm4, xmm5, 44h
|
||||
|
||||
mulps xmm0, [ones_over_32768]
|
||||
mulps xmm2, [ones_over_32768]
|
||||
mulps xmm4, [ones_over_2gig]
|
||||
|
||||
movaps xmm6, [ones]
|
||||
subps xmm6, xmm4 ; [ 1.0-1f][ 1.0-1f][ 1.0-2f][ 1.0-2f]
|
||||
|
||||
mulps xmm2, xmm4 ;
|
||||
mulps xmm0, xmm6 ; [1al* 1.0-1f][1ar*1.0-1f][2al*1.0-2f][2ar* 1.0-2f]
|
||||
addps xmm0, xmm2
|
||||
movups [edi], xmm0
|
||||
|
||||
add edi, 16
|
||||
dec ecx
|
||||
jnz near resample16Sunrolled
|
||||
|
||||
resample16Srolledstart:
|
||||
|
||||
add esp, 60h
|
||||
pop ebp
|
||||
mov ecx, [ebp+%$outlength]
|
||||
push ebp
|
||||
sub esp, 60h
|
||||
and ecx, 1
|
||||
%endif
|
||||
xorps xmm0, xmm0
|
||||
xorps xmm2, xmm2
|
||||
xorps xmm4, xmm4
|
||||
test ecx, ecx
|
||||
jz near resample16Sdone
|
||||
|
||||
resample16Srolled:
|
||||
|
||||
movsx ebp, word [esi*4]
|
||||
mov [samples + 0], ebp ; [ 1al][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+2]
|
||||
mov [samples + 4], ebp ; [ 1al][ 1ar][ ][ ]
|
||||
|
||||
movsx ebp, word [esi*4+4]
|
||||
mov [samplesplus1 + 0], ebp ; [ 1bl][ ][ ][ ]
|
||||
movsx ebp, word [esi*4+6]
|
||||
mov [samplesplus1 + 4], ebp ; [ 1bl][ 1br][ ][ ]
|
||||
|
||||
mov ebp, eax
|
||||
shr ebp, 1
|
||||
mov [fracs + 0], ebp ; [ 1f][ ][ ][ ]
|
||||
mov [fracs + 4], ebp ; [ 1f][ 1f][ ][ ]
|
||||
add eax, ebx
|
||||
adc esi, edx
|
||||
|
||||
cvtpi2ps xmm0, [samples]
|
||||
cvtpi2ps xmm2, [samplesplus1]
|
||||
cvtpi2ps xmm4, [fracs]
|
||||
|
||||
mulps xmm0, [ones_over_32768]
|
||||
mulps xmm2, [ones_over_32768]
|
||||
mulps xmm4, [ones_over_2gig]
|
||||
movups xmm6, [ones]
|
||||
subps xmm6, xmm4 ; [ 1.0-1f][ 1.0-1f][ ][ ]
|
||||
|
||||
mulps xmm2, xmm4 ;
|
||||
mulps xmm0, xmm6 ; [1a * 1.0-1f][2a *1.0-1f][3a *1.0-3f][4a * 1.0-4f]
|
||||
addps xmm0, xmm2
|
||||
movlps [edi], xmm0
|
||||
|
||||
add edi, 8
|
||||
dec ecx
|
||||
jnz near resample16Srolled
|
||||
|
||||
resample16Sdone:
|
||||
|
||||
add esp, 60h
|
||||
pop ebp
|
||||
|
||||
; restore position
|
||||
mov ecx, [ebp + %$position]
|
||||
mov [ecx + 0], eax
|
||||
|
||||
mov eax, [ebp + %$src]
|
||||
shr eax, 2
|
||||
sub esi, eax
|
||||
mov ecx, [ebp + %$position]
|
||||
mov [ecx + 4], esi
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
endproc
|
||||
|
||||
487
fmod/win32/src/fmod_dsp_winampplugin.cpp
Executable file
487
fmod/win32/src/fmod_dsp_winampplugin.cpp
Executable file
|
|
@ -0,0 +1,487 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WINAMPPLUGIN
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_dsp_winampplugin.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
#define BUFFERSIZE 256
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
FMOD_DSP_DESCRIPTION_EX dspwinampplugin;
|
||||
|
||||
#ifdef PLUGIN_EXPORTS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
FMODGetDSPDescription is mandantory for every fmod plugin. This is the symbol the registerplugin function searches for.
|
||||
Must be declared with F_API to make it export as stdcall.
|
||||
*/
|
||||
F_DECLSPEC F_DLLEXPORT FMOD_DSP_DESCRIPTION_EX * F_API FMODGetDSPDescriptionEx()
|
||||
{
|
||||
return DSPWinampPlugin::getDescriptionEx();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PLUGIN_EXPORTS */
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_DSP_DESCRIPTION_EX *DSPWinampPlugin::getDescriptionEx()
|
||||
{
|
||||
FMOD_memset(&dspwinampplugin, 0, sizeof(FMOD_DSP_DESCRIPTION_EX));
|
||||
|
||||
// name and version is stamped in later.
|
||||
dspwinampplugin.create = DSPWinampPlugin::createCallback;
|
||||
dspwinampplugin.release = DSPWinampPlugin::releaseCallback;
|
||||
dspwinampplugin.reset = DSPWinampPlugin::resetCallback;
|
||||
dspwinampplugin.read = DSPWinampPlugin::readCallback;
|
||||
|
||||
dspwinampplugin.setparameter = DSPWinampPlugin::setParameterCallback;
|
||||
dspwinampplugin.getparameter = DSPWinampPlugin::getParameterCallback;
|
||||
dspwinampplugin.config = DSPWinampPlugin::configCallback;
|
||||
|
||||
dspwinampplugin.mType = FMOD_DSP_TYPE_WINAMPPLUGIN;
|
||||
dspwinampplugin.mCategory = FMOD_DSP_CATEGORY_FILTER;
|
||||
dspwinampplugin.mSize = sizeof(DSPWinampPlugin);
|
||||
|
||||
return &dspwinampplugin;
|
||||
}
|
||||
|
||||
|
||||
short *DSPWinampPlugin::mEffectBuffer = NULL;
|
||||
int DSPWinampPlugin::mEffectBufferCount = 0;
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::createInternal()
|
||||
{
|
||||
int result;
|
||||
|
||||
if (mEffectBufferCount == 0)
|
||||
{
|
||||
mEffectBuffer = (short *)FMOD_Memory_Alloc(sizeof(short) * BUFFERSIZE);
|
||||
if (!mEffectBuffer)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
mEffectBufferCount++;
|
||||
|
||||
result = mEffect->Init(mEffect);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return FMOD_ERR_PLUGIN;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::releaseInternal()
|
||||
{
|
||||
mEffectBufferCount--;
|
||||
|
||||
if (mEffectBufferCount == 0)
|
||||
{
|
||||
FMOD_Memory_Free(mEffectBuffer);
|
||||
mEffectBuffer = NULL;
|
||||
}
|
||||
|
||||
mEffect->Quit(mEffect);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::resetInternal()
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::readInternal(float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
||||
{
|
||||
int count;
|
||||
int rate;
|
||||
int remaining = length * outchannels;
|
||||
|
||||
mSystem->getSoftwareFormat(&rate, 0, 0, 0, 0, 0);
|
||||
|
||||
while(remaining > 0)
|
||||
{
|
||||
int size = remaining;
|
||||
|
||||
if (size > BUFFERSIZE)
|
||||
{
|
||||
size = BUFFERSIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
Convert from float to short
|
||||
*/
|
||||
for (count = 0; count < size; count++)
|
||||
{
|
||||
float val = *inbuffer++;
|
||||
|
||||
mEffectBuffer[count] = (short)(val < -1.0f ? -32767 : val > 1.0f ? 32767 : val * 32767.0f);
|
||||
|
||||
}
|
||||
|
||||
mEffect->ModifySamples(mEffect, mEffectBuffer, size / outchannels, 16, outchannels, rate);
|
||||
|
||||
/*
|
||||
Convert back to floating point data
|
||||
*/
|
||||
for (count = 0; count < size; count++)
|
||||
{
|
||||
*outbuffer++ = (float)mEffectBuffer[count] / 32767.0f;
|
||||
}
|
||||
|
||||
remaining -= size;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::setParameterInternal(int index, float value)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::getParameterInternal(int index, float *value, char *valuestr)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT DSPWinampPlugin::showConfigDialogInternal(void *hwnd, int show)
|
||||
{
|
||||
mEffect->hwndParent = hwnd;
|
||||
|
||||
mEffect->Config(mEffect);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================================================
|
||||
|
||||
CALLBACK INTERFACE
|
||||
|
||||
==============================================================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::createCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->createInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::releaseCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->releaseInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::resetCallback(FMOD_DSP_STATE *dsp)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->resetInternal();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::readCallback(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->readInternal(inbuffer, outbuffer, length, inchannels, outchannels);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::setParameterCallback(FMOD_DSP_STATE *dsp, int index, float value)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->setParameterInternal(index, value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::getParameterCallback(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->getParameterInternal(index, value, valuestr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT F_CALLBACK DSPWinampPlugin::configCallback(FMOD_DSP_STATE *dsp, void *hwnd, int show)
|
||||
{
|
||||
DSPWinampPlugin *winamp = (DSPWinampPlugin *)dsp;
|
||||
|
||||
return winamp->showConfigDialogInternal(hwnd, show);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
49
fmod/win32/src/fmod_dsp_winampplugin.h
Executable file
49
fmod/win32/src/fmod_dsp_winampplugin.h
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef _FMOD_DSP_WINAMPPLUGIN_H
|
||||
#define _FMOD_DSP_WINAMPPLUGIN_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WINAMPPLUGIN
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_dsp_filter.h"
|
||||
|
||||
#include "../lib/winamp/dsp.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class DSPWinampPlugin : public DSPFilter
|
||||
{
|
||||
private:
|
||||
|
||||
static short *mEffectBuffer;
|
||||
static int mEffectBufferCount;
|
||||
|
||||
FMOD_RESULT createInternal();
|
||||
FMOD_RESULT releaseInternal();
|
||||
FMOD_RESULT resetInternal();
|
||||
FMOD_RESULT readInternal(float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
FMOD_RESULT setParameterInternal(int index, float value);
|
||||
FMOD_RESULT getParameterInternal(int index, float *value, char *valuestr);
|
||||
FMOD_RESULT showConfigDialogInternal(void *hwnd, int show);
|
||||
|
||||
public:
|
||||
|
||||
winampDSPModule *mEffect;
|
||||
|
||||
static FMOD_DSP_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
static FMOD_RESULT F_CALLBACK createCallback(FMOD_DSP_STATE *dsp);
|
||||
static FMOD_RESULT F_CALLBACK releaseCallback(FMOD_DSP_STATE *dsp);
|
||||
static FMOD_RESULT F_CALLBACK resetCallback(FMOD_DSP_STATE *dsp);
|
||||
static FMOD_RESULT F_CALLBACK readCallback(FMOD_DSP_STATE *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
static FMOD_RESULT F_CALLBACK setParameterCallback(FMOD_DSP_STATE *dsp, int index, float value);
|
||||
static FMOD_RESULT F_CALLBACK getParameterCallback(FMOD_DSP_STATE *dsp, int index, float *value, char *valuestr);
|
||||
static FMOD_RESULT F_CALLBACK configCallback(FMOD_DSP_STATE *dsp, void *hwnd, int show);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
461
fmod/win32/src/fmod_eax2.h
Executable file
461
fmod/win32/src/fmod_eax2.h
Executable file
|
|
@ -0,0 +1,461 @@
|
|||
/******************************************************************
|
||||
*
|
||||
* EAX.H - DirectSound3D Environmental Audio Extensions version 2.0
|
||||
* Updated July 8, 1999
|
||||
*
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
#ifndef EAX_H_INCLUDED
|
||||
#define EAX_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
#include <dxsdkver.h>
|
||||
#if (_DXSDK_PRODUCT_MAJOR < 9 || (_DXSDK_PRODUCT_MAJOR == 9 && _DXSDK_PRODUCT_MINOR < 21))
|
||||
#include <dplay.h> /* This defines DWORD_PTR for dsound.h to use. */
|
||||
#endif
|
||||
#include <dsound.h>
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION == 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else
|
||||
#include "../../lib/openal/include/al/al.h"
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // !GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID FAR name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extension {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 2.0 listener property set {0306A6A8-B224-11d2-99E5-0000E8D8C722}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties,
|
||||
0x306a6a8,
|
||||
0xb224,
|
||||
0x11d2,
|
||||
0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX20_ListenerProperties
|
||||
#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX20_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
|
||||
DSPROPERTY_EAXLISTENER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times are in seconds
|
||||
// - the reference for high frequency controls is 5 kHz
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
{
|
||||
long lRoom; // room effect level at low frequencies
|
||||
long lRoomHF; // room effect high-frequency level re. low frequency level
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flDecayTime; // reverberation decay time at low frequencies
|
||||
float flDecayHFRatio; // high-frequency to low-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
unsigned long dwEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
float flAirAbsorptionHF; // change in level per meter at 5 kHz
|
||||
unsigned long dwFlags; // modifies the behavior of properties
|
||||
} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// Used by DSPROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAXLISTENERFLAGS_RESERVED 0xFFFFFFC0 // reserved future use
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define EAXLISTENER_MINROOM (-10000)
|
||||
#define EAXLISTENER_MAXROOM 0
|
||||
#define EAXLISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAXLISTENER_MINROOMHF (-10000)
|
||||
#define EAXLISTENER_MAXROOMHF 0
|
||||
#define EAXLISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXLISTENER_MINDECAYTIME 0.1f
|
||||
#define EAXLISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAXLISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAXLISTENER_MAXREFLECTIONS 1000
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAXLISTENER_MINREVERB (-10000)
|
||||
#define EAXLISTENER_MAXREVERB 2000
|
||||
#define EAXLISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAXLISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENT 0
|
||||
#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 2.0 buffer property set {0306A6A7-B224-11d2-99E5-0000E8D8C722}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties,
|
||||
0x306a6a7,
|
||||
0xb224,
|
||||
0x11d2,
|
||||
0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX20_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXBUFFER_NONE,
|
||||
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_DIRECT,
|
||||
DSPROPERTY_EAXBUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOM,
|
||||
DSPROPERTY_EAXBUFFER_ROOMHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_FLAGS
|
||||
} DSPROPERTY_EAX_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
|
||||
DSPROPERTY_EAXBUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAXBUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level
|
||||
long lDirectHF; // direct path level at high frequencies
|
||||
long lRoom; // room effect level
|
||||
long lRoomHF; // room effect level at high frequencies
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // occlusion room effect level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long dwFlags; // modifies the behavior of properties
|
||||
} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
|
||||
|
||||
// Used by DSPROPERTY_EAXBUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define EAXBUFFER_MINDIRECT (-10000)
|
||||
#define EAXBUFFER_MAXDIRECT 1000
|
||||
#define EAXBUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAXBUFFER_MINDIRECTHF (-10000)
|
||||
#define EAXBUFFER_MAXDIRECTHF 0
|
||||
#define EAXBUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOM (-10000)
|
||||
#define EAXBUFFER_MAXROOM 1000
|
||||
#define EAXBUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAXBUFFER_MINROOMHF (-10000)
|
||||
#define EAXBUFFER_MAXROOMHF 0
|
||||
#define EAXBUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAXBUFFER_MAXOBSTRUCTION 0
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXOCCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 0.5f
|
||||
|
||||
#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMHFAUTO)
|
||||
|
||||
// Material transmission presets
|
||||
// 3 values in this order:
|
||||
// 1: occlusion (or obstruction)
|
||||
// 2: occlusion LF Ratio (or obstruction LF Ratio)
|
||||
// 3: occlusion Room Ratio
|
||||
|
||||
// Single window material preset
|
||||
#define EAX_MATERIAL_SINGLEWINDOW (-2800)
|
||||
#define EAX_MATERIAL_SINGLEWINDOWLF 0.71f
|
||||
#define EAX_MATERIAL_SINGLEWINDOWROOMRATIO 0.43f
|
||||
|
||||
// Double window material preset
|
||||
#define EAX_MATERIAL_DOUBLEWINDOW (-5000)
|
||||
#define EAX_MATERIAL_DOUBLEWINDOWHF 0.40f
|
||||
#define EAX_MATERIAL_DOUBLEWINDOWROOMRATIO 0.24f
|
||||
|
||||
// Thin door material preset
|
||||
#define EAX_MATERIAL_THINDOOR (-1800)
|
||||
#define EAX_MATERIAL_THINDOORLF 0.66f
|
||||
#define EAX_MATERIAL_THINDOORROOMRATIO 0.66f
|
||||
|
||||
// Thick door material preset
|
||||
#define EAX_MATERIAL_THICKDOOR (-4400)
|
||||
#define EAX_MATERIAL_THICKDOORLF 0.64f
|
||||
#define EAX_MATERIAL_THICKDOORROOMRTATION 0.27f
|
||||
|
||||
// Wood wall material preset
|
||||
#define EAX_MATERIAL_WOODWALL (-4000)
|
||||
#define EAX_MATERIAL_WOODWALLLF 0.50f
|
||||
#define EAX_MATERIAL_WOODWALLROOMRATIO 0.30f
|
||||
|
||||
// Brick wall material preset
|
||||
#define EAX_MATERIAL_BRICKWALL (-5000)
|
||||
#define EAX_MATERIAL_BRICKWALLLF 0.60f
|
||||
#define EAX_MATERIAL_BRICKWALLROOMRATIO 0.24f
|
||||
|
||||
// Stone wall material preset
|
||||
#define EAX_MATERIAL_STONEWALL (-6000)
|
||||
#define EAX_MATERIAL_STONEWALLLF 0.68f
|
||||
#define EAX_MATERIAL_STONEWALLROOMRATIO 0.20f
|
||||
|
||||
// Curtain material preset
|
||||
#define EAX_MATERIAL_CURTAIN (-1200)
|
||||
#define EAX_MATERIAL_CURTAINLF 0.15f
|
||||
#define EAX_MATERIAL_CURTAINROOMRATIO 1.00f
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
536
fmod/win32/src/fmod_eax3.h
Executable file
536
fmod/win32/src/fmod_eax3.h
Executable file
|
|
@ -0,0 +1,536 @@
|
|||
/*******************************************************************\
|
||||
* *
|
||||
* EAX.H - Environmental Audio Extensions version 3.0 *
|
||||
* for OpenAL and DirectSound3D *
|
||||
* *
|
||||
********************************************************************/
|
||||
|
||||
#ifndef EAX3_H_INCLUDED
|
||||
#define EAX3_H_INCLUDED
|
||||
|
||||
#include <dxsdkver.h>
|
||||
#if (_DXSDK_PRODUCT_MAJOR < 9 || (_DXSDK_PRODUCT_MAJOR == 9 && _DXSDK_PRODUCT_MINOR < 21))
|
||||
#include <dplay.h> /* This defines DWORD_PTR for dsound.h to use. */
|
||||
#endif
|
||||
#include <dsound.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
|
||||
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION == 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else // OPENAL
|
||||
#include "../../lib/openal/include/al/al.h"
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // !GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID /*FAR*/ name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extension
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties,
|
||||
0xa8fa6882,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMLF,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_DECAYLFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSPAN,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERBPAN,
|
||||
DSPROPERTY_EAXLISTENER_ECHOTIME,
|
||||
DSPROPERTY_EAXLISTENER_ECHODEPTH,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONTIME,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONDEPTH,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAXLISTENER_HFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_LFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
|
||||
DSPROPERTY_EAXLISTENER_IMMEDIATE)
|
||||
|
||||
typedef struct _EAXVECTOR {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} EAXVECTOR;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times and delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
{
|
||||
unsigned long ulEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
long lRoom; // room effect level (at mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lRoomLF; // relative room effect level at low frequencies
|
||||
float flDecayTime; // reverberation decay time at mid frequencies
|
||||
float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio
|
||||
float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
EAXVECTOR vReflectionsPan; // early reflections panning vector
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
EAXVECTOR vReverbPan; // late reverberation panning vector
|
||||
float flEchoTime; // echo time
|
||||
float flEchoDepth; // echo depth
|
||||
float flModulationTime; // modulation time
|
||||
float flModulationDepth; // modulation depth
|
||||
float flAirAbsorptionHF; // change in level per meter at high frequencies
|
||||
float flHFReference; // reference high frequency
|
||||
float flLFReference; // reference low frequency
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_UNDEFINED,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// Used by DSPROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time
|
||||
#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENT 0
|
||||
#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAXLISTENER_MINROOM (-10000)
|
||||
#define EAXLISTENER_MAXROOM 0
|
||||
#define EAXLISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAXLISTENER_MINROOMHF (-10000)
|
||||
#define EAXLISTENER_MAXROOMHF 0
|
||||
#define EAXLISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAXLISTENER_MINROOMLF (-10000)
|
||||
#define EAXLISTENER_MAXROOMLF 0
|
||||
#define EAXLISTENER_DEFAULTROOMLF 0
|
||||
|
||||
#define EAXLISTENER_MINDECAYTIME 0.1f
|
||||
#define EAXLISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAXLISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAXLISTENER_MINDECAYLFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYLFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAXLISTENER_MAXREFLECTIONS 1000
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAXLISTENER_MINREVERB (-10000)
|
||||
#define EAXLISTENER_MAXREVERB 2000
|
||||
#define EAXLISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAXLISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAXLISTENER_MINECHOTIME 0.075f
|
||||
#define EAXLISTENER_MAXECHOTIME 0.25f
|
||||
#define EAXLISTENER_DEFAULTECHOTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINECHODEPTH 0.0f
|
||||
#define EAXLISTENER_MAXECHODEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTECHODEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONTIME 0.04f
|
||||
#define EAXLISTENER_MAXMODULATIONTIME 4.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONDEPTH 0.0f
|
||||
#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAXLISTENER_MINHFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
#define EAXLISTENER_MINLFREFERENCE 20.0f
|
||||
#define EAXLISTENER_MAXLFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f
|
||||
|
||||
#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties,
|
||||
0xa8fa6881,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties
|
||||
#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXBUFFER_NONE,
|
||||
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_DIRECT,
|
||||
DSPROPERTY_EAXBUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOM,
|
||||
DSPROPERTY_EAXBUFFER_ROOMHF,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAXBUFFER_DOPPLERFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_FLAGS
|
||||
} DSPROPERTY_EAX_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
|
||||
DSPROPERTY_EAXBUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAXBUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level (at low and mid frequencies)
|
||||
long lDirectHF; // relative direct path level at high frequencies
|
||||
long lRoom; // room effect level (at low and mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // relative occlusion control for room effect
|
||||
float flOcclusionDirectRatio; // relative occlusion control for direct path
|
||||
long lExclusion; // main exlusion control (attenuation at high frequencies)
|
||||
float flExclusionLFRatio; // exclusion low-frequency level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flDopplerFactor; // like DS3D flDopplerFactor but per source
|
||||
float flRolloffFactor; // like DS3D flRolloffFactor but per source
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
typedef struct _EAXOBSTRUCTIONPROPERTIES
|
||||
{
|
||||
long lObstruction;
|
||||
float flObstructionLFRatio;
|
||||
} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION
|
||||
typedef struct _EAXOCCLUSIONPROPERTIES
|
||||
{
|
||||
long lOcclusion;
|
||||
float flOcclusionLFRatio;
|
||||
float flOcclusionRoomRatio;
|
||||
float flOcclusionDirectRatio;
|
||||
} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION
|
||||
typedef struct _EAXEXCLUSIONPROPERTIES
|
||||
{
|
||||
long lExclusion;
|
||||
float flExclusionLFRatio;
|
||||
} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES;
|
||||
|
||||
// Used by DSPROPERTY_EAXBUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXBUFFER_MINDIRECT (-10000)
|
||||
#define EAXBUFFER_MAXDIRECT 1000
|
||||
#define EAXBUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAXBUFFER_MINDIRECTHF (-10000)
|
||||
#define EAXBUFFER_MAXDIRECTHF 0
|
||||
#define EAXBUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOM (-10000)
|
||||
#define EAXBUFFER_MAXROOM 1000
|
||||
#define EAXBUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAXBUFFER_MINROOMHF (-10000)
|
||||
#define EAXBUFFER_MAXROOMHF 0
|
||||
#define EAXBUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAXBUFFER_MAXOBSTRUCTION 0
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXOCCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXEXCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTEXCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAXBUFFER_MINDOPPLERFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXDOPPLERFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMHFAUTO )
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
1535
fmod/win32/src/fmod_eax4.h
Executable file
1535
fmod/win32/src/fmod_eax4.h
Executable file
File diff suppressed because it is too large
Load diff
2067
fmod/win32/src/fmod_eax5.h
Executable file
2067
fmod/win32/src/fmod_eax5.h
Executable file
File diff suppressed because it is too large
Load diff
624
fmod/win32/src/fmod_file_cdda.cpp
Executable file
624
fmod/win32/src/fmod_file_cdda.cpp
Executable file
|
|
@ -0,0 +1,624 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_CDDA
|
||||
|
||||
#include "fmod_debug.h"
|
||||
#include "fmod_file_cdda.h"
|
||||
#include "fmod_os_cdda.h"
|
||||
#include "fmod_string.h"
|
||||
#include "fmod_time.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
CddaFile::CddaFile()
|
||||
{
|
||||
mDevice = 0;
|
||||
mLastTimeAccessed = 0;
|
||||
mGotUserToc = false;
|
||||
mJitterCorrection = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::init(bool force_aspi, bool jitter_correction)
|
||||
{
|
||||
mJitterCorrection = jitter_correction;
|
||||
return FMOD_OS_CDDA_Init(force_aspi);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::shutDown()
|
||||
{
|
||||
return FMOD_OS_CDDA_Shutdown();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::reallyOpen(const char *name_or_data, unsigned int *filesize)
|
||||
{
|
||||
int numtracks;
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
|
||||
mReadBuf = 0;
|
||||
mReadPtr = 0;
|
||||
mReadSizebytes = 0;
|
||||
mStartSector = 0;
|
||||
mCurrentSector = 0;
|
||||
mSectorsLeft = 0;
|
||||
mSectorsInChunk = 26;
|
||||
mJitterBuf = 0;
|
||||
mJitterBufSectors = 7;
|
||||
mJitterBufEmpty = true;
|
||||
mGotUserToc = false;
|
||||
|
||||
result = FMOD_OS_CDDA_OpenDevice((char *)name_or_data, &mDevice);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!FMOD_OS_CDDA_TestUnitReady(mDevice))
|
||||
{
|
||||
FMOD_OS_CDDA_DEBUGPRINT("CddaFile::reallyOpen: Device not ready (Make sure there's a CD/DVD in the drive!)");
|
||||
return FMOD_ERR_CDDA_NODISC;
|
||||
}
|
||||
|
||||
result = FMOD_OS_CDDA_ReadTocRaw(mDevice, &mDevice->toc);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
result = FMOD_OS_CDDA_ReadToc(mDevice, &mDevice->toc);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FMOD_OS_CDDA_DUMPTOC
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0;i < mDevice->toc.num_tracks;i++)
|
||||
{
|
||||
unsigned int len = (((mDevice->toc.num_sectors[i] * SIZEOF_CDDA_SECTOR) >> 2) / 44100) * 1000;
|
||||
FMOD_OS_CDDA_DEBUGPRINT("Track %d. 0x%08lx %d:%d (%d)\n", mDevice->toc.track_number[i], mDevice->toc.start_sector[i], len / 1000 / 60, len / 1000 % 60, *((unsigned char *)&mDevice->toc.flags[i]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mReadBuf = (char *)FMOD_Memory_Alloc(mSectorsInChunk * SIZEOF_CDDA_SECTOR);
|
||||
if (!mReadBuf)
|
||||
{
|
||||
reallyClose();
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
FMOD_memset(mReadBuf, 0, mSectorsInChunk * SIZEOF_CDDA_SECTOR);
|
||||
|
||||
if (mJitterCorrection)
|
||||
{
|
||||
mJitterBuf = (char *)FMOD_Memory_Alloc(SIZEOF_CDDA_SECTOR);
|
||||
if (!mJitterBuf)
|
||||
{
|
||||
reallyClose();
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
FMOD_memset(mJitterBuf, 0, SIZEOF_CDDA_SECTOR);
|
||||
mJitterBufEmpty = true;
|
||||
}
|
||||
|
||||
result = getNumTracks(&numtracks);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (numtracks < 1)
|
||||
{
|
||||
FMOD_OS_CDDA_DEBUGPRINT("CddaFile::reallyOpen: No audio tracks! (Please insert a CD/DVD that contains one or more audio tracks)\n");
|
||||
return FMOD_ERR_CDDA_NOAUDIO;
|
||||
}
|
||||
|
||||
result = getTrackLength(0, filesize);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
*filesize <<= 3;
|
||||
mDevice->usertoc.numtracks--;
|
||||
|
||||
FMOD_OS_CDDA_DEBUGPRINT("CddaFile::reallyOpen: ok\n");
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::reallyClose()
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
|
||||
if (mDevice)
|
||||
{
|
||||
result = FMOD_OS_CDDA_CloseDevice(mDevice);
|
||||
mDevice = 0;
|
||||
}
|
||||
|
||||
if (mReadBuf)
|
||||
{
|
||||
FMOD_Memory_Free(mReadBuf);
|
||||
mReadBuf = 0;
|
||||
}
|
||||
|
||||
if (mJitterBuf)
|
||||
{
|
||||
FMOD_Memory_Free(mJitterBuf);
|
||||
mJitterBuf = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::reallyRead(void *buffer, unsigned int size, unsigned int *rd)
|
||||
{
|
||||
int bytestocopy, count;
|
||||
unsigned int sectors_to_read = 0;
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
#ifdef FMOD_OS_CDDA_DEBUG
|
||||
unsigned int starttime;
|
||||
FMOD_OS_Time_GetMs(&starttime);
|
||||
#endif
|
||||
|
||||
if (!mDevice)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*rd = 0;
|
||||
|
||||
while (size)
|
||||
{
|
||||
if (!mReadSizebytes)
|
||||
{
|
||||
sectors_to_read = (mSectorsLeft < mSectorsInChunk) ? mSectorsLeft : mSectorsInChunk;
|
||||
if (!sectors_to_read)
|
||||
{
|
||||
*rd = 0;
|
||||
return FMOD_ERR_FILE_EOF;
|
||||
}
|
||||
|
||||
for (count = 0; count < 10; count++)
|
||||
{
|
||||
result = FMOD_OS_CDDA_ReadSectors(mDevice, mReadBuf, mCurrentSector, sectors_to_read);
|
||||
if (result == FMOD_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMOD_OS_Time_Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
FMOD_OS_Time_GetMs(&mLastTimeAccessed);
|
||||
|
||||
if (count >= 10)
|
||||
{
|
||||
return FMOD_ERR_CDDA_READ;
|
||||
}
|
||||
|
||||
if (mJitterCorrection)
|
||||
{
|
||||
doJitterCorrection(sectors_to_read);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentSector += sectors_to_read;
|
||||
mSectorsLeft -= sectors_to_read;
|
||||
mReadPtr = mReadBuf;
|
||||
mReadSizebytes = sectors_to_read * SIZEOF_CDDA_SECTOR;
|
||||
}
|
||||
|
||||
#ifdef FMOD_OS_CDDA_DEBUG
|
||||
{
|
||||
unsigned int elapsed;
|
||||
FMOD_OS_Time_GetMs(&elapsed);
|
||||
elapsed -= starttime;
|
||||
FMOD_OS_CDDA_AddProfileData((int)elapsed, mReadSizebytes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bytestocopy = (mReadSizebytes < (unsigned int)size) ? mReadSizebytes : size;
|
||||
|
||||
FMOD_memcpy((char *)buffer, mReadPtr, bytestocopy);
|
||||
|
||||
*rd += bytestocopy;
|
||||
mReadPtr += bytestocopy;
|
||||
mReadSizebytes -= bytestocopy;
|
||||
|
||||
buffer = (void *)((char *)buffer + bytestocopy);
|
||||
size -= bytestocopy;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::doJitterCorrection(unsigned int sectors_to_read)
|
||||
{
|
||||
if (!mJitterBufEmpty)
|
||||
{
|
||||
int offset, skip_bytes;
|
||||
int compare_size = ((sectors_to_read < mJitterBufSectors ? sectors_to_read : mJitterBufSectors) - 1) * SIZEOF_CDDA_SECTOR;
|
||||
int start_compare = compare_size >> 1;
|
||||
char *ptr_forward, *ptr_back;
|
||||
bool found = false;
|
||||
|
||||
if ((compare_size <= 0) || (sectors_to_read <= (mJitterBufSectors >> 1)))
|
||||
{
|
||||
FMOD_memset(mReadBuf, 0, sectors_to_read * SIZEOF_CDDA_SECTOR);
|
||||
FMOD_memset(mJitterBuf, 0, SIZEOF_CDDA_SECTOR);
|
||||
mCurrentSector += sectors_to_read;
|
||||
mSectorsLeft -= sectors_to_read;
|
||||
mReadPtr = mReadBuf;
|
||||
mReadSizebytes = sectors_to_read * SIZEOF_CDDA_SECTOR;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
ptr_forward = ptr_back = (mReadBuf + start_compare);
|
||||
skip_bytes = start_compare;
|
||||
|
||||
for (offset=0;offset < start_compare;offset += 4, ptr_forward += 4, ptr_back -= 4)
|
||||
{
|
||||
if (!memcmp(ptr_forward, mJitterBuf, SIZEOF_CDDA_SECTOR))
|
||||
{
|
||||
skip_bytes = start_compare + offset + SIZEOF_CDDA_SECTOR;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!memcmp(ptr_back, mJitterBuf, SIZEOF_CDDA_SECTOR))
|
||||
{
|
||||
skip_bytes = start_compare - offset + SIZEOF_CDDA_SECTOR;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/*
|
||||
Jitter error - couldn't match up this read to the last one - it's gonna sound bad...
|
||||
*/
|
||||
skip_bytes = 0;
|
||||
}
|
||||
|
||||
if ((unsigned int)sectors_to_read == mSectorsLeft)
|
||||
{
|
||||
mCurrentSector += sectors_to_read;
|
||||
mSectorsLeft -= sectors_to_read;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentSector += (sectors_to_read - (mJitterBufSectors >> 1) - 1);
|
||||
mSectorsLeft -= (sectors_to_read - (mJitterBufSectors >> 1) - 1);
|
||||
}
|
||||
mReadPtr = mReadBuf + skip_bytes;
|
||||
mReadSizebytes = (sectors_to_read * SIZEOF_CDDA_SECTOR) - skip_bytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentSector += sectors_to_read;
|
||||
mSectorsLeft -= sectors_to_read;
|
||||
mReadPtr = mReadBuf;
|
||||
mReadSizebytes = sectors_to_read * SIZEOF_CDDA_SECTOR;
|
||||
}
|
||||
|
||||
FMOD_memcpy(mJitterBuf, mReadBuf + ((sectors_to_read - 1) * SIZEOF_CDDA_SECTOR), SIZEOF_CDDA_SECTOR);
|
||||
mJitterBufEmpty = false;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::reallySeek(unsigned int pos)
|
||||
{
|
||||
unsigned int num_sectors;
|
||||
|
||||
pos /= SIZEOF_CDDA_SECTOR;
|
||||
|
||||
num_sectors = (mCurrentSector - mStartSector) + mSectorsLeft;
|
||||
if (pos >= num_sectors)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
mCurrentSector = mStartSector + pos;
|
||||
mSectorsLeft = num_sectors - pos;
|
||||
|
||||
FMOD_memset(mReadBuf, 0, mSectorsInChunk * SIZEOF_CDDA_SECTOR);
|
||||
mReadPtr = 0;
|
||||
mReadSizebytes = 0;
|
||||
mJitterBufEmpty = true;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::getNumTracks(int *numtracks)
|
||||
{
|
||||
if (!numtracks || !mDevice)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*numtracks = mDevice->toc.num_tracks - 1;
|
||||
if (*numtracks < 0)
|
||||
{
|
||||
*numtracks = 0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::getTrackLength(unsigned int track, unsigned int *tracklength)
|
||||
{
|
||||
if (!tracklength || !mDevice || (track >= (mDevice->toc.num_tracks - 1)))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*tracklength = mDevice->toc.num_sectors[track] * SIZEOF_CDDA_SECTOR;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::openTrack(unsigned int track)
|
||||
{
|
||||
unsigned int starttime, thistime;
|
||||
|
||||
if (track >= (mDevice->toc.num_tracks - 1)) /* -1 for leadout track */
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
mStartSector = mDevice->toc.start_sector[track];
|
||||
mCurrentSector = mStartSector;
|
||||
mSectorsLeft = mDevice->toc.num_sectors[track];
|
||||
mLength = mSectorsLeft * SIZEOF_CDDA_SECTOR;
|
||||
mReadPtr = 0;
|
||||
mReadSizebytes = 0;
|
||||
mJitterBufEmpty = true;
|
||||
FMOD_memset(mReadBuf, 0, mSectorsInChunk * SIZEOF_CDDA_SECTOR);
|
||||
|
||||
FMOD_OS_Time_GetMs(&thistime);
|
||||
if ((thistime - mLastTimeAccessed) > (FMOD_CDDA_SPINDOWN_TIME * 1000))
|
||||
{
|
||||
FMOD_OS_CDDA_SetSpeed(mDevice, 4);
|
||||
|
||||
FMOD_OS_Time_GetMs(&starttime);
|
||||
for (;;)
|
||||
{
|
||||
FMOD_OS_Time_GetMs(&thistime);
|
||||
if ((thistime - starttime) > (FMOD_CDDA_SPINUP_TIME * 1000))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
FMOD_OS_CDDA_ReadSectors(mDevice, mReadBuf, mStartSector, 1);
|
||||
FMOD_OS_Time_Sleep(20);
|
||||
}
|
||||
|
||||
FMOD_OS_Time_GetMs(&mLastTimeAccessed);
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT CddaFile::getMetadata(Metadata **metadata)
|
||||
{
|
||||
if (!mDevice || !metadata)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (mGotUserToc)
|
||||
{
|
||||
return FMOD_ERR_TAGNOTFOUND;
|
||||
}
|
||||
|
||||
mMetadata.addTag(FMOD_TAGTYPE_FMOD, "CDTOC", &mDevice->usertoc, sizeof(FMOD_CDTOC), FMOD_TAGDATATYPE_CDTOC, true);
|
||||
mGotUserToc = true;
|
||||
*metadata = &mMetadata;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
FMOD_RESULT CddaFile::getMemoryUsedImpl(MemoryTracker *tracker)
|
||||
{
|
||||
tracker->add(false, FMOD_MEMBITS_FILE, sizeof(CddaFile));
|
||||
|
||||
return File::getMemoryUsedImpl(tracker);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
2809
fmod/win32/src/fmod_os_cdda.cpp
Executable file
2809
fmod/win32/src/fmod_os_cdda.cpp
Executable file
File diff suppressed because it is too large
Load diff
829
fmod/win32/src/fmod_os_misc.cpp
Executable file
829
fmod/win32/src/fmod_os_misc.cpp
Executable file
|
|
@ -0,0 +1,829 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_os_misc.h"
|
||||
#include "fmod_memory.h"
|
||||
|
||||
#include "MeteredSection.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
|
||||
#define USEMETEREDSECTIONS
|
||||
|
||||
int gSizeofCriticalSection = sizeof(CRITICAL_SECTION);
|
||||
#ifdef USEMETEREDSECTIONS
|
||||
int gSizeofSemaphore = sizeof(METERED_SECTION);
|
||||
#else
|
||||
int gSizeofSemaphore = 0;
|
||||
#endif
|
||||
|
||||
#if defined(FMOD_DEBUG) && !defined(PLATFORM_WINDOWS64)
|
||||
|
||||
#define MS_VC_EXCEPTION 0x406D1388
|
||||
|
||||
typedef struct tagTHREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
|
||||
static void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
|
||||
info.dwType = 0x1000;
|
||||
info.szName = szThreadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD*)&info);
|
||||
}
|
||||
__except(EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
OS based memory alloc
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
void *FMOD_OS_Memory_Alloc(int size, FMOD_MEMORY_TYPE type)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
OS based memory re-alloc.
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
void *FMOD_OS_Memory_Realloc(void *ptr, int size, FMOD_MEMORY_TYPE type)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
OS based free
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
void FMOD_OS_Memory_Free(void *ptr, FMOD_MEMORY_TYPE type)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_DriveStatus()
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_Open(const char *name, char *mode, int unicode, unsigned int *filesize, void **handle)
|
||||
{
|
||||
if (unicode)
|
||||
{
|
||||
*handle = CreateFileW((WCHAR *)name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
*handle = CreateFileA(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
|
||||
if (*handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND && err != ERROR_INVALID_NAME)
|
||||
{
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
}
|
||||
|
||||
return FMOD_ERR_FILE_NOTFOUND;
|
||||
}
|
||||
|
||||
*filesize = GetFileSize(*handle, NULL);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_Close(void *handle)
|
||||
{
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_Cancel(void *handle)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_Read(void *handle, void *buf, unsigned int count, unsigned int *read)
|
||||
{
|
||||
DWORD rd;
|
||||
|
||||
if (!ReadFile(handle, buf, count, &rd, NULL))
|
||||
{
|
||||
DWORD lasterr = GetLastError();
|
||||
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
}
|
||||
|
||||
*read = rd;
|
||||
|
||||
if (rd != count)
|
||||
{
|
||||
return FMOD_ERR_FILE_EOF;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_File_Seek(void *handle, unsigned int offset)
|
||||
{
|
||||
DWORD retval;
|
||||
|
||||
retval = SetFilePointer(handle, offset, NULL, FILE_BEGIN);
|
||||
|
||||
if (retval == (unsigned int)-1)
|
||||
{
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
Debug to console function
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Debug_OutputStr(const char *s)
|
||||
{
|
||||
OutputDebugStringA(s);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
Gets the current time in nanoseconds. (1000th of a millisecond)
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Time_GetNs(unsigned int *ns)
|
||||
{
|
||||
LARGE_INTEGER val,freq;
|
||||
|
||||
if (QueryPerformanceCounter(&val))
|
||||
{
|
||||
QueryPerformanceFrequency(&freq);
|
||||
val.QuadPart *= 1000;
|
||||
val.QuadPart *= 1000;
|
||||
val.QuadPart /= freq.QuadPart;
|
||||
|
||||
*ns = val.LowPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ns = timeGetTime() * 1000;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
Gets the current time in milliseconds. (1000th of a second)
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Time_GetMs(unsigned int *ms)
|
||||
{
|
||||
*ms = timeGetTime();
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Time_Sleep(unsigned int ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Thread_GetCurrentID(FMOD_UINT_NATIVE *id)
|
||||
{
|
||||
*id = GetCurrentThreadId();
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
'priority' -1 to 2, -1 = low 0 = normal, 1 = high, 2 = critical
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Thread_Create(const char *name, THREAD_RETURNTYPE (THREAD_CALLCONV *func)(void *param), void *param, FMOD_THREAD_PRIORITY priority, void *stack, int stacksize, void **handle)
|
||||
{
|
||||
HRESULT hr;
|
||||
unsigned int id;
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*handle = (void *)_beginthreadex(NULL, stacksize, func, param,0, (unsigned int *)&id);
|
||||
if (!*handle)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case FMOD_THREAD_PRIORITY_VERYLOW:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_LOWEST);
|
||||
break;
|
||||
case FMOD_THREAD_PRIORITY_LOW:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_BELOW_NORMAL);
|
||||
break;
|
||||
case FMOD_THREAD_PRIORITY_NORMAL:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_NORMAL);
|
||||
break;
|
||||
case FMOD_THREAD_PRIORITY_HIGH:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
break;
|
||||
case FMOD_THREAD_PRIORITY_VERYHIGH:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_HIGHEST);
|
||||
break;
|
||||
case FMOD_THREAD_PRIORITY_CRITICAL:
|
||||
hr = SetThreadPriority(*handle, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
break;
|
||||
};
|
||||
|
||||
#if defined(FMOD_DEBUG) && !defined(PLATFORM_WINDOWS64)
|
||||
SetThreadName(id, name);
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Thread_Destroy(void *handle)
|
||||
{
|
||||
CloseHandle(handle);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
CRITICAL_SECTION gMemoryCrit;
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_CriticalSection_Create(FMOD_OS_CRITICALSECTION **crit, bool memorycrit)
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
|
||||
if (!crit)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (memorycrit)
|
||||
{
|
||||
*crit = (FMOD_OS_CRITICALSECTION *)&gMemoryCrit; /* Can't use alloc on the critical section used in the memory system. */
|
||||
}
|
||||
else
|
||||
{
|
||||
*crit = (FMOD_OS_CRITICALSECTION *)FMOD_Memory_Alloc(sizeof(CRITICAL_SECTION));
|
||||
if (!*crit)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeCriticalSection((CRITICAL_SECTION *)(*crit));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_CriticalSection_Free(FMOD_OS_CRITICALSECTION *crit, bool memorycrit)
|
||||
{
|
||||
if (!crit)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
DeleteCriticalSection((CRITICAL_SECTION *)crit);
|
||||
|
||||
if (memorycrit)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
FMOD_Memory_Free(crit);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_CriticalSection_Enter(FMOD_OS_CRITICALSECTION *crit)
|
||||
{
|
||||
if (!crit)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
EnterCriticalSection((CRITICAL_SECTION *)crit);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_CriticalSection_Leave(FMOD_OS_CRITICALSECTION *crit)
|
||||
{
|
||||
if (!crit)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
LeaveCriticalSection((CRITICAL_SECTION *)crit);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Semaphore_Create(FMOD_OS_SEMAPHORE **sema)
|
||||
{
|
||||
if (!sema)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
#ifdef USEMETEREDSECTIONS
|
||||
*sema = (FMOD_OS_SEMAPHORE *)CreateMeteredSection(0, 0xffff, NULL);
|
||||
if (!*sema)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
#else
|
||||
*sema = (FMOD_OS_SEMAPHORE *)CreateSemaphore(NULL, 0, 0xffff, NULL);
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Semaphore_Free(FMOD_OS_SEMAPHORE *sema)
|
||||
{
|
||||
if (sema == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
#ifdef USEMETEREDSECTIONS
|
||||
CloseMeteredSection((LPMETERED_SECTION)sema);
|
||||
#else
|
||||
CloseHandle((HANDLE)sema);
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Semaphore_Wait(FMOD_OS_SEMAPHORE *sema)
|
||||
{
|
||||
if (sema == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
#ifdef USEMETEREDSECTIONS
|
||||
EnterMeteredSection((LPMETERED_SECTION)sema, INFINITE);
|
||||
#else
|
||||
WaitForSingleObject((HANDLE)sema, INFINITE);
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Semaphore_Signal(FMOD_OS_SEMAPHORE *sema, bool interrupt)
|
||||
{
|
||||
if (sema == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
#ifdef USEMETEREDSECTIONS
|
||||
LeaveMeteredSection((LPMETERED_SECTION)sema, 1, NULL);
|
||||
#else
|
||||
ReleaseSemaphore((HANDLE)sema, 1, NULL);
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Library_Load(const char *dllname, FMOD_OS_LIBRARY **handle)
|
||||
{
|
||||
if (!dllname || !handle)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*handle = (FMOD_OS_LIBRARY *)LoadLibraryA(dllname);
|
||||
if (!*handle)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
|
||||
return FMOD_ERR_FILE_NOTFOUND;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Library_GetProcAddress(FMOD_OS_LIBRARY *handle, const char *procname, void **address)
|
||||
{
|
||||
if (!handle || !address)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*address = (void *)GetProcAddress((HMODULE)handle, procname);
|
||||
if (!*address)
|
||||
{
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Library_Free(FMOD_OS_LIBRARY *handle)
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!FreeLibrary((HMODULE)handle))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_CheckDriverList(bool *devicelistchanged)
|
||||
{
|
||||
static int lastNumDrivers = -1;
|
||||
int numDrivers = -1;
|
||||
|
||||
numDrivers = waveOutGetNumDevs();
|
||||
numDrivers += waveInGetNumDevs();
|
||||
|
||||
*devicelistchanged = (numDrivers != lastNumDrivers && lastNumDrivers != -1);
|
||||
lastNumDrivers = numDrivers;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
|
||||
extern FMOD_OS_CRITICALSECTION *gResolveCrit;
|
||||
|
||||
int FMOD_OS_GetMemoryUsed()
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
if (gResolveCrit)
|
||||
{
|
||||
total += gSizeofCriticalSection;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
#endif
|
||||
41
fmod/win32/src/fmod_os_misc_asm.s
Executable file
41
fmod/win32/src/fmod_os_misc_asm.s
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
%include "./FMOD_static/win32/src/c32.mac"
|
||||
|
||||
; ==========================================================================================
|
||||
; GLOBAL UNINITIALIZED DATA
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .data use32 align=32]
|
||||
|
||||
; ==========================================================================================
|
||||
; CODE
|
||||
; ==========================================================================================
|
||||
|
||||
[SEGMENT .text use32 align=32]
|
||||
|
||||
; =================================================================================================================================
|
||||
; int FMOD_OS_SupportsSSE
|
||||
; =================================================================================================================================
|
||||
proc FMOD_OS_SupportsSSE
|
||||
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov eax, 1
|
||||
cpuid
|
||||
test edx, 02000000h
|
||||
jnz SSEFound
|
||||
mov eax, 0
|
||||
jmp SSETestEnd
|
||||
SSEFound:
|
||||
mov eax, 1
|
||||
SSETestEnd:
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
endproc
|
||||
501
fmod/win32/src/fmod_os_net.cpp
Executable file
501
fmod/win32/src/fmod_os_net.cpp
Executable file
|
|
@ -0,0 +1,501 @@
|
|||
#include "fmod_net.h"
|
||||
#include "fmod_os_misc.h"
|
||||
#include "fmod_time.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
static const int FMOD_NET_MAXADDRLEN = 46;
|
||||
|
||||
static int FMOD_OS_Net_Init_Count = 0;
|
||||
|
||||
FMOD_OS_CRITICALSECTION *gResolveCrit = 0;
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Init()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
if (FMOD_OS_Net_Init_Count == 0)
|
||||
{
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(0x0002, &wsadata);
|
||||
|
||||
result = FMOD_OS_CriticalSection_Create(&gResolveCrit);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
WSACleanup();
|
||||
return result;
|
||||
}
|
||||
|
||||
FMOD_OS_Net_Init_Count++;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Shutdown()
|
||||
{
|
||||
if (FMOD_OS_Net_Init_Count > 0)
|
||||
{
|
||||
FMOD_OS_Net_Init_Count--;
|
||||
if (FMOD_OS_Net_Init_Count == 0)
|
||||
{
|
||||
FMOD_OS_CriticalSection_Free(gResolveCrit);
|
||||
gResolveCrit = 0;
|
||||
|
||||
WSACleanup();
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Connect(const char *host, const unsigned short port, void **handle)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
struct hostent *h;
|
||||
FMOD_RESULT result;
|
||||
SOCKET sock;
|
||||
int rc;
|
||||
struct timeval tv;
|
||||
unsigned long nonblocking = 1;
|
||||
fd_set writefd;
|
||||
unsigned int thistime = 0, lasttime = 0, elapsedtime = 0;
|
||||
unsigned int timeout = FMOD_Net_Timeout;
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
*handle = (void *)sock;
|
||||
}
|
||||
|
||||
FMOD_memset(&server, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
*((unsigned long *)&server.sin_addr) = inet_addr(host);
|
||||
|
||||
if (*((unsigned long *)&server.sin_addr) == INADDR_NONE)
|
||||
{
|
||||
char buf[MAXGETHOSTSTRUCT];
|
||||
HANDLE handle;
|
||||
|
||||
result = FMOD_OS_CriticalSection_Enter(gResolveCrit);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
closesocket(sock);
|
||||
return result;
|
||||
}
|
||||
|
||||
FMOD_memset(buf, 0, MAXGETHOSTSTRUCT);
|
||||
|
||||
handle = WSAAsyncGetHostByName(NULL, NULL, host, buf, MAXGETHOSTSTRUCT);
|
||||
|
||||
h = (struct hostent *)buf;
|
||||
|
||||
FMOD_OS_Time_GetMs(&lasttime);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (h->h_name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
FMOD_OS_Time_GetMs(&thistime);
|
||||
|
||||
elapsedtime += (thistime - lasttime);
|
||||
lasttime = thistime;
|
||||
|
||||
if (elapsedtime >= timeout)
|
||||
{
|
||||
WSACancelAsyncRequest(handle);
|
||||
FMOD_OS_CriticalSection_Leave(gResolveCrit);
|
||||
return FMOD_ERR_NET_URL;
|
||||
}
|
||||
|
||||
FMOD_OS_Time_Sleep(10);
|
||||
}
|
||||
|
||||
FMOD_memcpy(&server.sin_addr, (struct in_addr *)h->h_addr, sizeof(struct in_addr));
|
||||
FMOD_OS_CriticalSection_Leave(gResolveCrit);
|
||||
}
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
|
||||
FD_ZERO(&writefd);
|
||||
FD_SET(sock, &writefd);
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
|
||||
rc = connect(sock, (struct sockaddr *)&server, sizeof(server));
|
||||
if (rc == SOCKET_ERROR)
|
||||
{
|
||||
int rc = WSAGetLastError();
|
||||
|
||||
if (rc != WSAEWOULDBLOCK)
|
||||
{
|
||||
closesocket(sock);
|
||||
return FMOD_ERR_NET_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Select will block for timeout length, or return when connected
|
||||
*/
|
||||
rc = select(0, 0, &writefd, 0, &tv);
|
||||
if (rc <= 0)
|
||||
{
|
||||
closesocket(sock);
|
||||
return FMOD_ERR_NET_CONNECT;
|
||||
}
|
||||
|
||||
nonblocking = 0;
|
||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
Begin listening on the designated port, non-blocking
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Listen(const unsigned short port, void **listenhandle)
|
||||
{
|
||||
SOCKET listensocket;
|
||||
SOCKADDR_IN address;
|
||||
u_long nonblocking = TRUE;
|
||||
|
||||
// Create the socket
|
||||
listensocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listensocket == INVALID_SOCKET)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
// Set blocking mode
|
||||
if (ioctlsocket(listensocket, FIONBIO, &nonblocking) == SOCKET_ERROR)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
// Set to listen from any IP on the defined port
|
||||
FMOD_memset(&address, 0, sizeof(address));
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(port);
|
||||
address.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
|
||||
|
||||
// Bind the address to the socket
|
||||
if (bind(listensocket, (struct sockaddr*)&address, sizeof(address)) == SOCKET_ERROR)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
// Start listening for connections
|
||||
if (listen(listensocket, 3) == SOCKET_ERROR)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
*listenhandle = (void *)listensocket;
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
Accept a pending connection from the queue
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Accept(const void *listenhandle, void **clienthandle)
|
||||
{
|
||||
SOCKET listensocket = (SOCKET)listenhandle;
|
||||
SOCKET clientsocket = NULL;
|
||||
|
||||
if (listenhandle == (void *)-1)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
// Accept a waiting connection
|
||||
clientsocket = accept(listensocket, NULL, NULL);
|
||||
if(clientsocket == INVALID_SOCKET)
|
||||
{
|
||||
int errorcode = WSAGetLastError();
|
||||
if(errorcode == WSAEWOULDBLOCK)
|
||||
{
|
||||
return FMOD_ERR_NET_WOULD_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*clienthandle = (void *)clientsocket;
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Close(const void *handle)
|
||||
{
|
||||
SOCKET sock = (SOCKET)handle;
|
||||
|
||||
if (sock != -1)
|
||||
{
|
||||
closesocket(sock);
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Write(const void *handle, const char *buf, const unsigned int len, unsigned int *byteswritten)
|
||||
{
|
||||
SOCKET sock = (SOCKET)handle;
|
||||
int written, bytestowrite = len;
|
||||
|
||||
if (handle == (void *)-1)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
*byteswritten = 0;
|
||||
|
||||
while (bytestowrite)
|
||||
{
|
||||
written = send(sock, buf, bytestowrite, 0);
|
||||
if (written == SOCKET_ERROR)
|
||||
{
|
||||
int errorcode = WSAGetLastError();
|
||||
if(errorcode == WSAEWOULDBLOCK)
|
||||
{
|
||||
return FMOD_ERR_NET_WOULD_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*byteswritten += written;
|
||||
bytestowrite -= written;
|
||||
buf += written;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_Read(const void *handle, char *buf, const unsigned int len, unsigned int *bytesread)
|
||||
{
|
||||
SOCKET sock = (SOCKET)handle;
|
||||
int read, bytestoread = len;
|
||||
|
||||
if (handle == (void *)-1)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if (!buf || (len <= 0))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*bytesread = 0;
|
||||
|
||||
while (bytestoread)
|
||||
{
|
||||
read = recv(sock, buf, bytestoread, 0);
|
||||
|
||||
if (read == SOCKET_ERROR)
|
||||
{
|
||||
int errorcode = WSAGetLastError();
|
||||
if(errorcode == WSAEWOULDBLOCK)
|
||||
{
|
||||
return FMOD_ERR_NET_WOULD_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
else if (read == 0)
|
||||
{
|
||||
/*
|
||||
Connection closed gracefully
|
||||
*/
|
||||
return FMOD_ERR_FILE_EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bytesread += read;
|
||||
bytestoread -= read;
|
||||
buf += read;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Net_ReadLine(const void *handle, char *buf, const unsigned int len)
|
||||
{
|
||||
unsigned int pos, read;
|
||||
char c = 0;
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
if (handle == (void *)-1)
|
||||
{
|
||||
return FMOD_ERR_NET_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if (!buf || (len <= 0))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
|
||||
while (pos < len)
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OS_Net_Read(handle, &c, 1, &read);
|
||||
if (result == FMOD_ERR_NET_WOULD_BLOCK)
|
||||
{
|
||||
return FMOD_ERR_NET_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
if (read == 1)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (c != '\r')
|
||||
{
|
||||
buf[pos++] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= len)
|
||||
{
|
||||
pos = len - 1;
|
||||
}
|
||||
|
||||
buf[pos] = 0;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
112
fmod/win32/src/fmod_os_output.cpp
Executable file
112
fmod/win32/src/fmod_os_output.cpp
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_memory.h"
|
||||
#include "fmod_output.h"
|
||||
#include "fmod_output_asio.h"
|
||||
#include "fmod_output_wasapi.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_output_winmm.h"
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_pluginfactory.h"
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Output_Register(FMOD::PluginFactory *pluginfactory)
|
||||
{
|
||||
#ifdef FMOD_USE_PLUGINS
|
||||
|
||||
CHECK_RESULT(pluginfactory->tryLoadPlugin("output_dsound"));
|
||||
CHECK_RESULT(pluginfactory->tryLoadPlugin("output_winmm"));
|
||||
CHECK_RESULT(pluginfactory->tryLoadPlugin("output_wasapi"));
|
||||
CHECK_RESULT(pluginfactory->tryLoadPlugin("output_asio"));
|
||||
|
||||
#else
|
||||
|
||||
#ifdef FMOD_SUPPORT_DSOUND
|
||||
CHECK_RESULT(pluginfactory->registerOutput(FMOD::OutputDSound::getDescriptionEx()));
|
||||
#endif
|
||||
#ifdef FMOD_SUPPORT_WINMM
|
||||
CHECK_RESULT(pluginfactory->registerOutput(FMOD::OutputWinMM::getDescriptionEx()));
|
||||
#endif
|
||||
#ifdef FMOD_SUPPORT_WASAPI
|
||||
CHECK_RESULT(pluginfactory->registerOutput(FMOD::OutputWASAPI::getDescriptionEx()));
|
||||
#endif
|
||||
#ifdef FMOD_SUPPORT_ASIO
|
||||
CHECK_RESULT(pluginfactory->registerOutput(FMOD::OutputASIO::getDescriptionEx()));
|
||||
#endif
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
CHECK_RESULT(pluginfactory->registerOutput(FMOD::OutputOpenAL::getDescriptionEx()));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT FMOD_OS_Output_GetDefault(FMOD_OUTPUTTYPE *outputtype)
|
||||
{
|
||||
if (!outputtype)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
*outputtype = FMOD_OUTPUTTYPE_DSOUND;
|
||||
|
||||
#ifdef FMOD_SUPPORT_WASAPI
|
||||
/*
|
||||
Check COM support for WASAPI, override default output mode if supported
|
||||
*/
|
||||
{
|
||||
IMMDeviceEnumerator *enumerator = NULL;
|
||||
HRESULT hResult = S_OK;
|
||||
|
||||
hResult = CoInitialize(NULL);
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator)))
|
||||
{
|
||||
*outputtype = FMOD_OUTPUTTYPE_WASAPI;
|
||||
enumerator->Release();
|
||||
}
|
||||
|
||||
if (hResult == S_OK || hResult == S_FALSE)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
1812
fmod/win32/src/fmod_output_asio.cpp
Executable file
1812
fmod/win32/src/fmod_output_asio.cpp
Executable file
File diff suppressed because it is too large
Load diff
101
fmod/win32/src/fmod_output_asio.h
Executable file
101
fmod/win32/src/fmod_output_asio.h
Executable file
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef _FMOD_OUTPUT_ASIO_H
|
||||
#define _FMOD_OUTPUT_ASIO_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_ASIO
|
||||
|
||||
#include "fmod_outputi.h"
|
||||
|
||||
#include "asio\asiosys.h"
|
||||
#include "asio\asio.h"
|
||||
#include "asio\asiodrivers.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class OutputASIO : public Output
|
||||
{
|
||||
private:
|
||||
|
||||
AsioDrivers *mHandle;
|
||||
long mInputChannels;
|
||||
long mOutputChannels;
|
||||
long mBufferMinSize;
|
||||
long mBufferMaxSize;
|
||||
long mBufferPreferredSize;
|
||||
long mBufferGranularity;
|
||||
bool mPostOutput;
|
||||
float *mInterleavedBuffer;
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
float *mInterleavedRecordBuffer;
|
||||
unsigned int mInterleavedRecordBufferPos;
|
||||
bool mRecordLoop;
|
||||
SoundI *mRecordSound;
|
||||
FMOD_SOUND_FORMAT mRecordFormat;
|
||||
unsigned int mRecordBufferLength;
|
||||
#endif
|
||||
|
||||
ASIOCallbacks mCallbacks;
|
||||
ASIOBufferInfo *mBufferInfo;
|
||||
ASIOChannelInfo *mChannelInfo;
|
||||
|
||||
|
||||
static void bufferSwitch(long index, ASIOBool processNow);
|
||||
static ASIOTime * bufferSwitchTimeInfo(ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);
|
||||
static void sampleRateDidChange(ASIOSampleRate sRate);
|
||||
static long asioMessage(long selector, long value, void* message, double* opt);
|
||||
|
||||
#ifdef FMOD_SUPPORT_SOFTWARE
|
||||
FMOD_RESULT updateMixer(ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
static FMOD_OUTPUT_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
FMOD_RESULT enumerate();
|
||||
FMOD_RESULT getNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT getDriverName(int id, char *name, int namelen);
|
||||
FMOD_RESULT getDriverCaps(int id, FMOD_CAPS *caps);
|
||||
FMOD_RESULT init(int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
|
||||
FMOD_RESULT close();
|
||||
FMOD_RESULT getHandle(void **handle);
|
||||
FMOD_RESULT start();
|
||||
FMOD_RESULT stop();
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
FMOD_RESULT recordEnumerate();
|
||||
FMOD_RESULT recordGetNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT recordGetDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordStart (FMOD_RECORDING_INFO *recordinfo, Sound *sound, bool loop);
|
||||
FMOD_RESULT recordStop (FMOD_RECORDING_INFO *recordinfo);
|
||||
FMOD_RESULT recordGetPosition (FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
FMOD_RESULT recordLock (FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT recordUnlock (FMOD_RECORDING_INFO *recordinfo, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
#endif
|
||||
|
||||
static FMOD_RESULT F_CALLBACK getNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK getDriverNameCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen);
|
||||
static FMOD_RESULT F_CALLBACK getDriverCapsCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps);
|
||||
static FMOD_RESULT F_CALLBACK initCallback (FMOD_OUTPUT_STATE *output, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK startCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK stopCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getHandleCallback (FMOD_OUTPUT_STATE *output, void **handle);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
static FMOD_RESULT F_CALLBACK recordGetNumDriversCallback(FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoCallback(FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordStartCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, FMOD_SOUND *sound, int loop);
|
||||
static FMOD_RESULT F_CALLBACK recordStopCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo);
|
||||
static FMOD_RESULT F_CALLBACK recordGetPositionCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK recordLockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
static FMOD_RESULT F_CALLBACK recordUnlockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* #ifdef FMOD_SUPPORT_ASIO */
|
||||
|
||||
#endif
|
||||
3211
fmod/win32/src/fmod_output_dsound.cpp
Executable file
3211
fmod/win32/src/fmod_output_dsound.cpp
Executable file
File diff suppressed because it is too large
Load diff
252
fmod/win32/src/fmod_output_dsound.h
Executable file
252
fmod/win32/src/fmod_output_dsound.h
Executable file
|
|
@ -0,0 +1,252 @@
|
|||
#ifndef _FMOD_OUTPUT_DSOUND_H
|
||||
#define _FMOD_OUTPUT_DSOUND_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_DSOUND
|
||||
|
||||
//#define FMOD_OUTPUT_DSOUND_USETIMER
|
||||
|
||||
#ifdef FMOD_OUTPUT_DSOUND_USETIMER
|
||||
#include "fmod_output_timer.h"
|
||||
#else
|
||||
#include "fmod_output_polled.h"
|
||||
#endif
|
||||
#include "fmod_os_misc.h"
|
||||
|
||||
#ifdef PLATFORM_32BIT
|
||||
typedef unsigned long DWORD;
|
||||
typedef DWORD DWORD_PTR;
|
||||
#endif
|
||||
|
||||
#include <dsound.h>
|
||||
|
||||
#ifndef _FMOD_MEMORYTRACKER_H
|
||||
#include "fmod_memorytracker.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
Directsound function pointers definitions.
|
||||
*/
|
||||
typedef HRESULT (WINAPI * PFN_DSCREATE) (LPGUID lpguid, LPDIRECTSOUND * ppDS, IUnknown FAR * pUnkOuter);
|
||||
typedef BOOL (WINAPI * PFN_DSENUMERATE) (LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext);
|
||||
typedef HRESULT (WINAPI * PFN_DSCREATE8) (LPCGUID lpcGuidDevice, LPDIRECTSOUND8 * ppDS8, LPUNKNOWN pUnkOuter);
|
||||
typedef HRESULT (WINAPI * PFN_DSCCREATE) (LPGUID lpGUID, LPDIRECTSOUNDCAPTURE *lplpDSC,LPUNKNOWN pUnkOuter);
|
||||
typedef BOOL (WINAPI * PFN_DSCENUMERATE) (LPDSENUMCALLBACKW lpDSEnumCallback,LPVOID lpContext);
|
||||
typedef HRESULT (WINAPI * PFN_DSCCREATE8) (LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE8 *lplpDSC, LPUNKNOWN pUnkOuter);
|
||||
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_I3DL2_ListenerProperties = { 0xDA0F0520, 0x300A, 0x11D3, { 0x8A, 0x2B, 0x00, 0x60, 0x97, 0x0D, 0xB0, 0x11 } };
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_I3DL2_BufferProperties = { 0xDA0F0521, 0x300A, 0x11D3, { 0x8A, 0x2B, 0x00, 0x60, 0x97, 0x0D, 0xB0, 0x11 } };
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_EAX20_BufferProperties = { 0x306a6a7, 0xb224, 0x11d2, { 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22 } };
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_EAX20_ListenerProperties = { 0x306a6a8, 0xb224, 0x11d2, { 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22 } };
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_EAX30_ListenerProperties = { 0xa8fa6882, 0xb476, 0x11d3, { 0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87 } };
|
||||
static const FMOD_GUID FMOD_DSPROPSETID_EAX30_BufferProperties = { 0xa8fa6881, 0xb476, 0x11d3, { 0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_Context = { 0x1d4870ad, 0xdef, 0x43c0, { 0xa4, 0xc, 0x52, 0x36, 0x32, 0x29, 0x63, 0x42 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_Source = { 0x1b86b823, 0x22df, 0x4eae, { 0x8b, 0x3c, 0x12, 0x78, 0xce, 0x54, 0x42, 0x27 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_FXSlot0 = { 0xc4d79f1e, 0xf1ac, 0x436b, { 0xa8, 0x1d, 0xa7, 0x38, 0xe7, 0x4, 0x54, 0x69 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_FXSlot1 = { 0x8c00e96, 0x74be, 0x4491, { 0x93, 0xaa, 0xe8, 0xad, 0x35, 0xa4, 0x91, 0x17 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_FXSlot2 = { 0x1d433b88, 0xf0f6, 0x4637, { 0x91, 0x9f, 0x60, 0xe7, 0xe0, 0x6b, 0x5e, 0xdd } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX40_FXSlot3 = { 0xefff08ea, 0xc7d8, 0x44ab, { 0x93, 0xad, 0x6d, 0xbd, 0x5f, 0x91, 0x0, 0x64 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_Context = { 0x57e13437, 0xb932, 0x4ab2, { 0xb8, 0xbd, 0x52, 0x66, 0xc1, 0xa8, 0x87, 0xee } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_Source = { 0x5edf82f0, 0x24a7, 0x4f38, { 0x8e, 0x64, 0x2f, 0x09, 0xca, 0x05, 0xde, 0xe1 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_FXSlot0 = { 0x91f9590f, 0xc388, 0x407a, { 0x84, 0xb0, 0x1b, 0xae, 0x0e, 0xf7, 0x1a, 0xbc } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_FXSlot1 = { 0x8f5f7aca, 0x9608, 0x4965, { 0x81, 0x37, 0x82, 0x13, 0xc7, 0xb9, 0xd9, 0xde } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_FXSlot2 = { 0x3c0f5252, 0x9834, 0x46f0, { 0xa1, 0xd8, 0x5b, 0x95, 0xc4, 0xa0, 0x0a, 0x30 } };
|
||||
static const FMOD_GUID FMOD_EAXPROPERTYID_EAX50_FXSlot3 = { 0xe2eb0eaa, 0xe806, 0x45e7, { 0x9f, 0x86, 0x06, 0xc1, 0x57, 0x1a, 0x6f, 0xa3 } };
|
||||
static const FMOD_GUID FMOD_EAX_NULL_GUID = { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
|
||||
static const FMOD_GUID FMOD_EAX_REVERB_EFFECT = { 0xcf95c8f, 0xa3cc, 0x4849, { 0xb0, 0xb6, 0x83, 0x2e, 0xcc, 0x18, 0x22, 0xdf } };
|
||||
static const FMOD_GUID FMOD_IID_IKsPropertySet = { 0x31efac30, 0x515c, 0x11d0, { 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 } };
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class ChannelDSound;
|
||||
class SampleDSound;
|
||||
class Sound;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
REVERB_VERSION_NONE,
|
||||
REVERB_VERSION_EAX5,
|
||||
REVERB_VERSION_EAX4,
|
||||
REVERB_VERSION_EAX3,
|
||||
REVERB_VERSION_EAX2,
|
||||
REVERB_VERSION_I3DL2
|
||||
} REVERB_VERSION;
|
||||
|
||||
typedef struct FMOD_DSoundRecordMembers
|
||||
{
|
||||
IDirectSoundCapture8 *mDirectSoundCapture;
|
||||
IDirectSoundCaptureBuffer *mDirectSoundCaptureBuffer;
|
||||
} FMOD_DSoundRecordMembers;
|
||||
|
||||
#ifdef FMOD_OUTPUT_DSOUND_USETIMER
|
||||
class OutputDSound : public OutputTimer
|
||||
#else
|
||||
class OutputDSound : public OutputPolled
|
||||
#endif
|
||||
{
|
||||
DECLARE_MEMORYTRACKER_NONVIRTUAL
|
||||
|
||||
friend class SampleDSound;
|
||||
friend class ChannelDSound;
|
||||
friend class ChannelDSoundEAX2;
|
||||
friend class ChannelDSoundEAX3;
|
||||
friend class ChannelDSoundEAX4;
|
||||
friend class ChannelDSoundI3DL2;
|
||||
|
||||
private:
|
||||
|
||||
bool mDLLInitialized;
|
||||
bool mCoInitialized;
|
||||
bool mGlobalFocus;
|
||||
bool mNeedToCommit;
|
||||
FMOD_INITFLAGS mInitFlags;
|
||||
|
||||
int mDirectXVersion;
|
||||
HMODULE mDSoundModule;
|
||||
HMODULE mDSound3DModule;
|
||||
|
||||
PFN_DSCREATE8 mDirectSoundCreate;
|
||||
PFN_DSENUMERATE mDirectSoundEnumerate;
|
||||
IDirectSound8 *mDirectSound;
|
||||
IDirectSound3DListener *mDirectSoundListener;
|
||||
|
||||
PFN_DSCENUMERATE mDirectSoundCaptureEnumerate;
|
||||
PFN_DSCCREATE8 mDirectSoundCaptureCreate;
|
||||
|
||||
REVERB_VERSION mReverbVersion;
|
||||
unsigned int mFeaturesReverb;
|
||||
IKsPropertySet *mBufferReverb;
|
||||
SampleDSound *mSampleReverb;
|
||||
|
||||
bool mUseSoftware2DBuffers;
|
||||
bool mUseSoftware3DBuffers;
|
||||
float mMinFrequency;
|
||||
float mMaxFrequency;
|
||||
unsigned int mBufferLength;
|
||||
unsigned int mNumBuffers;
|
||||
|
||||
float mLastDopplerScale;
|
||||
float mLastDistancerScale;
|
||||
float mLastRolloffrScale;
|
||||
|
||||
FMOD_SPEAKERMODE mSpeakerMode;
|
||||
|
||||
ChannelDSound *mChannel2D;
|
||||
ChannelDSound *mChannel3D;
|
||||
Sample *mSample;
|
||||
|
||||
unsigned int mBufferMemoryCurrent;
|
||||
unsigned int mBufferMemoryMax;
|
||||
|
||||
FMOD_RESULT registerDLL();
|
||||
|
||||
bool initI3DL2();
|
||||
FMOD_RESULT closeI3DL2();
|
||||
FMOD_RESULT setPropertiesI3DL2(const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT getPropertiesI3DL2(FMOD_REVERB_PROPERTIES *prop);
|
||||
bool querySupportI3DL2(unsigned int ulQuery);
|
||||
|
||||
bool initEAX2();
|
||||
FMOD_RESULT closeEAX2();
|
||||
FMOD_RESULT setPropertiesEAX2(const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT getPropertiesEAX2(FMOD_REVERB_PROPERTIES *prop);
|
||||
bool querySupportEAX2(unsigned int ulQuery);
|
||||
|
||||
bool initEAX3();
|
||||
FMOD_RESULT closeEAX3();
|
||||
FMOD_RESULT setPropertiesEAX3(const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT getPropertiesEAX3(FMOD_REVERB_PROPERTIES *prop);
|
||||
bool querySupportEAX3(unsigned int ulQuery);
|
||||
|
||||
bool initEAX4();
|
||||
FMOD_RESULT closeEAX4();
|
||||
FMOD_RESULT setPropertiesEAX4(const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT getPropertiesEAX4(FMOD_REVERB_PROPERTIES *prop);
|
||||
bool querySupportEAX4(FMOD_GUID guid, unsigned long ulProperty);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
int mNumDrivers; /* Public for C callback access */
|
||||
short *mDriverName[FMOD_OUTPUT_MAXDRIVERS]; /* Public for C callback access */
|
||||
GUID mGUID[FMOD_OUTPUT_MAXDRIVERS];
|
||||
|
||||
static FMOD_OUTPUT_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
FMOD_RESULT enumerate();
|
||||
FMOD_RESULT getNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT getDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverInfoW(int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverCapsEx(int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode, int *num2dchannels, int *num3dchannels, int *totalchannels);
|
||||
FMOD_RESULT init(int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, FMOD_SPEAKERMODE *speakermode, int dspbufferlength, int dspnumbuffers, int max2dchannels, int max3dchannels, void *extradriverdata);
|
||||
FMOD_RESULT close();
|
||||
FMOD_RESULT getHandle(void **handle);
|
||||
FMOD_RESULT update();
|
||||
FMOD_RESULT createSample(FMOD_MODE mode, FMOD_CODEC_WAVEFORMAT *waveformat, Sample **sample);
|
||||
FMOD_RESULT getSoundRAM(int *currentalloced, int *maxalloced, int *total);
|
||||
FMOD_RESULT setReverbProperties(const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT getReverbProperties(FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT start();
|
||||
FMOD_RESULT stop();
|
||||
FMOD_RESULT getPosition(unsigned int *pcm);
|
||||
FMOD_RESULT lock(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT unlock(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
int getSampleMaxChannels(FMOD_MODE mode, FMOD_SOUND_FORMAT format);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
int mRecordNumDrivers; /* Public for C callback access */
|
||||
short *mRecordDriverName[FMOD_OUTPUT_MAXDRIVERS]; /* Public for C callback access */
|
||||
GUID mRecordGUID[FMOD_OUTPUT_MAXDRIVERS];
|
||||
|
||||
FMOD_RESULT recordEnumerate();
|
||||
FMOD_RESULT recordGetNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT recordGetDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordGetDriverInfoW(int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordStart (FMOD_RECORDING_INFO *recordinfo, Sound *sound, bool loop);
|
||||
FMOD_RESULT recordStop (FMOD_RECORDING_INFO *recordinfo);
|
||||
FMOD_RESULT recordGetPosition (FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
FMOD_RESULT recordLock (FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT recordUnlock (FMOD_RECORDING_INFO *recordinfo, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
#endif
|
||||
|
||||
static FMOD_RESULT F_CALLBACK getNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverCapsExCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode, int *num2dchannels, int *num3dchannels, int *totalchannels);
|
||||
static FMOD_RESULT F_CALLBACK initExCallback (FMOD_OUTPUT_STATE *output, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, FMOD_SPEAKERMODE *speakermode, int dspbufferlength, int dspnumbuffers, int max2dchannels, int max3dchannels, void *extradriverdata);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK startCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK stopCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK updateCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getHandleCallback (FMOD_OUTPUT_STATE *output, void **handle);
|
||||
static FMOD_RESULT F_CALLBACK getPositionCallback (FMOD_OUTPUT_STATE *output, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK lockCallback (FMOD_OUTPUT_STATE *output, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
static FMOD_RESULT F_CALLBACK unlockCallback (FMOD_OUTPUT_STATE *output, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
static FMOD_RESULT F_CALLBACK createSampleCallback (FMOD_OUTPUT_STATE *output, FMOD_MODE mode, FMOD_CODEC_WAVEFORMAT *waveformat, Sample **sample);
|
||||
static FMOD_RESULT F_CALLBACK getSoundRAMCallback (FMOD_OUTPUT_STATE *output, int *currentalloced, int *maxalloced, int *total);
|
||||
static FMOD_RESULT F_CALLBACK setReverbPropertiesCallback (FMOD_OUTPUT_STATE *output, const FMOD_REVERB_PROPERTIES *prop);
|
||||
static int F_CALLBACK getSampleMaxChannelsCallback (FMOD_OUTPUT_STATE *output, FMOD_MODE mode, FMOD_SOUND_FORMAT format);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
static FMOD_RESULT F_CALLBACK recordGetNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordStartCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, FMOD_SOUND *sound, int loop);
|
||||
static FMOD_RESULT F_CALLBACK recordStopCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo);
|
||||
static FMOD_RESULT F_CALLBACK recordGetPositionCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK recordLockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
static FMOD_RESULT F_CALLBACK recordUnlockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
#endif
|
||||
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
static FMOD_RESULT F_CALLBACK getMemoryUsedCallback (FMOD_OUTPUT_STATE *output, MemoryTracker *tracker);
|
||||
#endif
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_DSOUND */
|
||||
|
||||
#endif
|
||||
353
fmod/win32/src/fmod_output_dsound_eax2.cpp
Executable file
353
fmod/win32/src/fmod_output_dsound_eax2.cpp
Executable file
|
|
@ -0,0 +1,353 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_eax2.h"
|
||||
#include "fmod_localcriticalsection.h"
|
||||
#include "fmod_sample_dsound.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::querySupportEAX2(unsigned int ulQuery)
|
||||
{
|
||||
unsigned long ulSupport = 0;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX2", "check properties %08X\n", ulQuery));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->QuerySupport(guid, ulQuery, &ulSupport);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (ulSupport&(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET)) ==
|
||||
(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET) )
|
||||
{
|
||||
mFeaturesReverb |= (DWORD)(1 << ulQuery);
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX2", "success.\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX2", "failed.\n"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::initEAX2()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
ULONG support = 0;
|
||||
HRESULT hr = DS_OK;
|
||||
GUID guid;
|
||||
FMOD_CODEC_WAVEFORMAT waveformat;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX2", "Querying EAX2\n"));
|
||||
|
||||
if (mBufferReverb)
|
||||
{
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Create EAX sample
|
||||
*/
|
||||
|
||||
FMOD_memset(&waveformat, 0, sizeof(FMOD_CODEC_WAVEFORMAT));
|
||||
waveformat.frequency = 44100;
|
||||
waveformat.lengthpcm = 1024;
|
||||
waveformat.channels = 1;
|
||||
waveformat.format = FMOD_SOUND_FORMAT_PCM16;
|
||||
|
||||
result = createSample(FMOD_3D | FMOD_UNIQUE, &waveformat, (Sample **)&mSampleReverb);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX2", "could not create hardware sample.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
mSampleReverb->mSystem = mSystem;
|
||||
|
||||
/*
|
||||
OBTAIN EAX INTERFACE TO BUFFER
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
if(mSampleReverb->mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb) != DS_OK)
|
||||
{
|
||||
mBufferReverb = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
QUERY FOR EAX support
|
||||
*/
|
||||
support = querySupportEAX2(DSPROPERTY_EAXLISTENER_NONE);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ENVIRONMENT);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ROOM);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ROOMHF);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_DECAYTIME);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_DECAYHFRATIO);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_REFLECTIONS);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_REVERB);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_REVERBDELAY);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR);
|
||||
if (support) support = querySupportEAX2(DSPROPERTY_EAXLISTENER_FLAGS);
|
||||
|
||||
if (!mFeaturesReverb)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX2", "failed EAX check, releasing reverb interface\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Turn down reverb to start with.
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ROOM))
|
||||
{
|
||||
DWORD Room = EAXLISTENER_MINROOM;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX2", "setting reverb environment to OFF\n"));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ROOM, 0, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX2", "found!\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::closeEAX2()
|
||||
{
|
||||
if (mBufferReverb)
|
||||
{
|
||||
/*
|
||||
Turn down reverb again
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ROOM))
|
||||
{
|
||||
GUID guid;
|
||||
DWORD Room = EAXLISTENER_MINROOM;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ROOM, 0, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = NULL;
|
||||
}
|
||||
|
||||
if (mSampleReverb)
|
||||
{
|
||||
mSampleReverb->release();
|
||||
mSampleReverb = NULL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::setPropertiesEAX2(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX2", "Entering \n"));
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS) )
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX2", "failed - apparently DSPROPERTY_EAXLISTENER_ALLPARAMETERS isnt supported\n"));
|
||||
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXLISTENERPROPERTIES dsprop = {0};
|
||||
GUID guid;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX2", "setting listener properties\n"));
|
||||
|
||||
dsprop.flEnvironmentSize = prop->EnvSize;
|
||||
dsprop.dwEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
dsprop.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
dsprop.lRoom = prop->Room;
|
||||
dsprop.lRoomHF = prop->RoomHF;
|
||||
dsprop.flDecayTime = prop->DecayTime;
|
||||
dsprop.flDecayHFRatio = prop->DecayHFRatio;
|
||||
dsprop.lReflections = prop->Reflections;
|
||||
dsprop.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
dsprop.lReverb = prop->Reverb;
|
||||
dsprop.flReverbDelay = prop->ReverbDelay;
|
||||
dsprop.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
dsprop.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprop.dwFlags = prop->Flags & 0xFF;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, 0, 0, &dsprop, sizeof(EAXLISTENERPROPERTIES));
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX2", "setting listener properties FAILED\n"));
|
||||
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::getPropertiesEAX2(FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS) )
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS))
|
||||
{
|
||||
GUID guid;
|
||||
HRESULT hr;
|
||||
EAXLISTENERPROPERTIES dsprop = {0};
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, 0, 0, &dsprop, sizeof(EAXLISTENERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Environment = dsprop.dwEnvironment;
|
||||
prop->EnvSize = dsprop.flEnvironmentSize ;
|
||||
prop->EnvDiffusion = dsprop.flEnvironmentDiffusion ;
|
||||
prop->Room = dsprop.lRoom ;
|
||||
prop->RoomHF = dsprop.lRoomHF ;
|
||||
prop->RoomLF = 0;
|
||||
prop->DecayTime = dsprop.flDecayTime ;
|
||||
prop->DecayHFRatio = dsprop.flDecayHFRatio ;
|
||||
prop->DecayLFRatio = 0;
|
||||
prop->Reflections = dsprop.lReflections ;
|
||||
prop->ReflectionsDelay = dsprop.flReflectionsDelay ;
|
||||
prop->ReflectionsPan[0] = 0;
|
||||
prop->ReflectionsPan[1] = 0;
|
||||
prop->ReflectionsPan[2] = 0;
|
||||
prop->Reverb = dsprop.lReverb ;
|
||||
prop->ReverbDelay = dsprop.flReverbDelay ;
|
||||
prop->ReverbPan[0] = 0;
|
||||
prop->ReverbPan[1] = 0;
|
||||
prop->ReverbPan[2] = 0;
|
||||
prop->EchoTime = 0;
|
||||
prop->EchoDepth = 0;
|
||||
prop->ModulationTime = 0;
|
||||
prop->ModulationDepth = 0;
|
||||
prop->AirAbsorptionHF = dsprop.flAirAbsorptionHF ;
|
||||
prop->HFReference = 0;
|
||||
prop->LFReference = 0;
|
||||
prop->RoomRolloffFactor = dsprop.flRoomRolloffFactor ;
|
||||
prop->Flags = dsprop.dwFlags ;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
381
fmod/win32/src/fmod_output_dsound_eax3.cpp
Executable file
381
fmod/win32/src/fmod_output_dsound_eax3.cpp
Executable file
|
|
@ -0,0 +1,381 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_eax3.h"
|
||||
#include "fmod_localcriticalsection.h"
|
||||
#include "fmod_sample_dsound.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::querySupportEAX3(unsigned int ulQuery)
|
||||
{
|
||||
unsigned long ulSupport = 0;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX3", "check properties %08X\n", ulQuery));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->QuerySupport(guid, ulQuery, &ulSupport);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (ulSupport&(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET)) ==
|
||||
(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET) )
|
||||
{
|
||||
mFeaturesReverb |= (DWORD)(1 << ulQuery);
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX3", "success\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX3", "failed.\n"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::initEAX3()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
ULONG support = 0;
|
||||
HRESULT hr = DS_OK;
|
||||
GUID guid;
|
||||
FMOD_CODEC_WAVEFORMAT waveformat;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "Querying EAX3\n"));
|
||||
|
||||
if (mBufferReverb)
|
||||
{
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Create EAX sample
|
||||
*/
|
||||
|
||||
FMOD_memset(&waveformat, 0, sizeof(FMOD_CODEC_WAVEFORMAT));
|
||||
waveformat.frequency = 44100;
|
||||
waveformat.lengthpcm = 1024;
|
||||
waveformat.channels = 1;
|
||||
waveformat.format = FMOD_SOUND_FORMAT_PCM16;
|
||||
|
||||
result = createSample(FMOD_3D | FMOD_UNIQUE, &waveformat, (Sample **)&mSampleReverb);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX3", "could not create hardware sample.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
mSampleReverb->mSystem = mSystem;
|
||||
|
||||
/*
|
||||
OBTAIN EAX INTERFACE TO BUFFER
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
if(mSampleReverb->mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb) != DS_OK)
|
||||
{
|
||||
mBufferReverb = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
QUERY FOR EAX support
|
||||
*/
|
||||
support = querySupportEAX3(DSPROPERTY_EAXLISTENER_NONE);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ENVIRONMENT);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ROOM);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ROOMHF);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ROOMLF);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_DECAYTIME);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_DECAYHFRATIO);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_DECAYLFRATIO);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REFLECTIONS);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REFLECTIONSPAN);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REVERB);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REVERBDELAY);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_REVERBPAN);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ECHOTIME);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ECHODEPTH);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_MODULATIONTIME);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_MODULATIONDEPTH);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_HFREFERENCE);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_LFREFERENCE);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR);
|
||||
if (support) support = querySupportEAX3(DSPROPERTY_EAXLISTENER_FLAGS);
|
||||
|
||||
if (!mFeaturesReverb)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX3", "failed EAX check, releasing reverb interface\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Turn down reverb to start with.
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ROOM))
|
||||
{
|
||||
DWORD Room = EAXLISTENER_MINROOM;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX3", "setting reverb environment to OFF\n"));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ROOM, NULL, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX3", "found!\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::closeEAX3()
|
||||
{
|
||||
if (mBufferReverb)
|
||||
{
|
||||
/*
|
||||
Turn down reverb again
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ROOM))
|
||||
{
|
||||
GUID guid;
|
||||
DWORD Room = EAXLISTENER_MINROOM;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ROOM, NULL, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = NULL;
|
||||
}
|
||||
|
||||
if (mSampleReverb)
|
||||
{
|
||||
mSampleReverb->release();
|
||||
mSampleReverb = NULL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::setPropertiesEAX3(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX3", "Entering \n"));
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS) )
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX3", "failed - apparently DSPROPERTY_EAXLISTENER_ALLPARAMETERS isnt supported\n"));
|
||||
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXLISTENERPROPERTIES dsprop = {0};
|
||||
GUID guid;
|
||||
|
||||
// FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX3", "setting listener properties\n"));
|
||||
|
||||
dsprop.ulEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
dsprop.flEnvironmentSize = prop->EnvSize;
|
||||
dsprop.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
dsprop.lRoom = prop->Room;
|
||||
dsprop.lRoomHF = prop->RoomHF;
|
||||
dsprop.lRoomLF = prop->RoomLF;
|
||||
dsprop.flDecayTime = prop->DecayTime;
|
||||
dsprop.flDecayHFRatio = prop->DecayHFRatio;
|
||||
dsprop.flDecayLFRatio = prop->DecayLFRatio;
|
||||
dsprop.lReflections = prop->Reflections;
|
||||
dsprop.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
dsprop.vReflectionsPan.x = prop->ReflectionsPan[0];
|
||||
dsprop.vReflectionsPan.y = prop->ReflectionsPan[1];
|
||||
dsprop.vReflectionsPan.z = prop->ReflectionsPan[2];
|
||||
dsprop.lReverb = prop->Reverb;
|
||||
dsprop.flReverbDelay = prop->ReverbDelay;
|
||||
dsprop.vReverbPan.x = prop->ReverbPan[0];
|
||||
dsprop.vReverbPan.y = prop->ReverbPan[1];
|
||||
dsprop.vReverbPan.z = prop->ReverbPan[2];
|
||||
dsprop.flEchoTime = prop->EchoTime;
|
||||
dsprop.flEchoDepth = prop->EchoDepth;
|
||||
dsprop.flModulationTime = prop->ModulationTime;
|
||||
dsprop.flModulationDepth = prop->ModulationDepth;
|
||||
dsprop.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
dsprop.flHFReference = prop->HFReference;
|
||||
dsprop.flLFReference = prop->LFReference;
|
||||
dsprop.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprop.ulFlags = prop->Flags & 0xFF;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, NULL, 0, &dsprop, sizeof(EAXLISTENERPROPERTIES));
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX3", "setting listener properties FAILED\n"));
|
||||
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::getPropertiesEAX3(FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS) )
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_EAXLISTENER_ALLPARAMETERS))
|
||||
{
|
||||
GUID guid;
|
||||
HRESULT hr;
|
||||
EAXLISTENERPROPERTIES dsprop = {0};
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, NULL, 0, &dsprop, sizeof(EAXLISTENERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Environment = dsprop.ulEnvironment ;
|
||||
prop->EnvSize = dsprop.flEnvironmentSize ;
|
||||
prop->EnvDiffusion = dsprop.flEnvironmentDiffusion ;
|
||||
prop->Room = dsprop.lRoom ;
|
||||
prop->RoomHF = dsprop.lRoomHF ;
|
||||
prop->RoomLF = dsprop.lRoomLF ;
|
||||
prop->DecayTime = dsprop.flDecayTime ;
|
||||
prop->DecayHFRatio = dsprop.flDecayHFRatio ;
|
||||
prop->DecayLFRatio = dsprop.flDecayLFRatio ;
|
||||
prop->Reflections = dsprop.lReflections ;
|
||||
prop->ReflectionsDelay = dsprop.flReflectionsDelay ;
|
||||
prop->ReflectionsPan[0] = dsprop.vReflectionsPan.x ;
|
||||
prop->ReflectionsPan[1] = dsprop.vReflectionsPan.y ;
|
||||
prop->ReflectionsPan[2] = dsprop.vReflectionsPan.z ;
|
||||
prop->Reverb = dsprop.lReverb ;
|
||||
prop->ReverbDelay = dsprop.flReverbDelay ;
|
||||
prop->ReverbPan[0] = dsprop.vReverbPan.x ;
|
||||
prop->ReverbPan[1] = dsprop.vReverbPan.y ;
|
||||
prop->ReverbPan[2] = dsprop.vReverbPan.z ;
|
||||
prop->EchoTime = dsprop.flEchoTime ;
|
||||
prop->EchoDepth = dsprop.flEchoDepth ;
|
||||
prop->ModulationTime = dsprop.flModulationTime ;
|
||||
prop->ModulationDepth = dsprop.flModulationDepth ;
|
||||
prop->AirAbsorptionHF = dsprop.flAirAbsorptionHF ;
|
||||
prop->HFReference = dsprop.flHFReference ;
|
||||
prop->LFReference = dsprop.flLFReference ;
|
||||
prop->RoomRolloffFactor = dsprop.flRoomRolloffFactor ;
|
||||
prop->Flags = dsprop.ulFlags ;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
|
||||
440
fmod/win32/src/fmod_output_dsound_eax4.cpp
Executable file
440
fmod/win32/src/fmod_output_dsound_eax4.cpp
Executable file
|
|
@ -0,0 +1,440 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_eax4.h"
|
||||
#include "fmod_localcriticalsection.h"
|
||||
#include "fmod_sample_dsound.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
bool gFXslot2set = false;
|
||||
bool gFXslot3set = false;
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::querySupportEAX4(FMOD_GUID guid, unsigned long ulProperty)
|
||||
{
|
||||
HRESULT hr;
|
||||
unsigned long ulSupport;
|
||||
GUID g;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX4", "check properties %08X\n", ulProperty));
|
||||
|
||||
FMOD_memcpy(&g, &guid, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->QuerySupport(g, ulProperty, &ulSupport);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (ulSupport&(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET)) ==
|
||||
(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET) )
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX4", "success.\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportEAX4", "failed.\n"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::initEAX4()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
ULONG support = 0;
|
||||
HRESULT hr = DS_OK;
|
||||
GUID guid;
|
||||
FMOD_CODEC_WAVEFORMAT waveformat;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "Querying EAX4\n"));
|
||||
|
||||
if (mBufferReverb)
|
||||
{
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Create EAX sample
|
||||
*/
|
||||
|
||||
FMOD_memset(&waveformat, 0, sizeof(FMOD_CODEC_WAVEFORMAT));
|
||||
waveformat.frequency = 44100;
|
||||
waveformat.lengthpcm = 1024;
|
||||
waveformat.channels = 1;
|
||||
waveformat.format = FMOD_SOUND_FORMAT_PCM16;
|
||||
|
||||
result = createSample(FMOD_3D | FMOD_UNIQUE, &waveformat, (Sample **)&mSampleReverb);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "could not create hardware sample.\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
mSampleReverb->mSystem = mSystem;
|
||||
|
||||
|
||||
/*
|
||||
OBTAIN EAX INTERFACE TO BUFFER
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
if(mSampleReverb->mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb) != DS_OK)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "failed (1).\n"));
|
||||
|
||||
mBufferReverb = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
QUERY FOR EAX support
|
||||
*/
|
||||
support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_Context, EAXCONTEXT_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_FXSlot0, EAXFXSLOT_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_FXSlot1, EAXFXSLOT_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_FXSlot2, EAXFXSLOT_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_FXSlot3, EAXFXSLOT_ALLPARAMETERS);
|
||||
if (support) support = querySupportEAX4(FMOD_EAXPROPERTYID_EAX40_Source, EAXSOURCE_ALLPARAMETERS);
|
||||
|
||||
if (support)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "EAX 4.0 - success\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "failed (2).\n"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Turn down reverb to start with
|
||||
*/
|
||||
{
|
||||
long room = EAXREVERB_MINROOM;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "setting reverb environment to OFF\n"));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
hr = mBufferReverb->Set(guid, EAXREVERB_ROOM, 0, 0, &room, sizeof(long));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "failed (3).\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initEAX4", "found!\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::closeEAX4()
|
||||
{
|
||||
GUID guid;
|
||||
long lock = EAXFXSLOT_UNLOCKED;
|
||||
|
||||
if (mBufferReverb)
|
||||
{
|
||||
/*
|
||||
Unlock FX slots
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
mBufferReverb->Set(guid, EAXFXSLOT_LOCKED, 0, 0, &lock, sizeof(long));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
mBufferReverb->Set(guid, EAXFXSLOT_LOCKED, 0, 0, &lock, sizeof(long));
|
||||
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = NULL;
|
||||
}
|
||||
|
||||
if (mSampleReverb)
|
||||
{
|
||||
mSampleReverb->release();
|
||||
mSampleReverb = NULL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::setPropertiesEAX4(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXREVERBPROPERTIES eaxprop = {0};
|
||||
EAXFXSLOTPROPERTIES fxslot;
|
||||
GUID guid;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch(prop->Instance)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
|
||||
if (!gFXslot2set)
|
||||
{
|
||||
FMOD_memcpy(&fxslot.guidLoadEffect, &FMOD_EAX_REVERB_EFFECT, sizeof(GUID));
|
||||
fxslot.lLock = EAXFXSLOT_LOCKED;
|
||||
fxslot.lVolume = 0;
|
||||
fxslot.ulFlags = EAXFXSLOTFLAGS_ENVIRONMENT;
|
||||
|
||||
hr = mBufferReverb->Set(guid, EAXFXSLOT_ALLPARAMETERS, NULL, 0, &fxslot, sizeof(EAXFXSLOTPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ULONG ulReceived;
|
||||
GUID effect;
|
||||
|
||||
/*
|
||||
Check if the slot contains a reverb. If so, we can still use that slot.
|
||||
*/
|
||||
hr = mBufferReverb->Get(guid, EAXFXSLOT_LOADEFFECT, NULL, 0, &effect, sizeof(GUID), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
if (memcmp(&effect, &fxslot.guidLoadEffect, sizeof(GUID)))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
gFXslot2set = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
|
||||
if (!gFXslot3set)
|
||||
{
|
||||
FMOD_memcpy(&fxslot.guidLoadEffect, &FMOD_EAX_REVERB_EFFECT, sizeof(GUID));
|
||||
fxslot.lLock = EAXFXSLOT_LOCKED;
|
||||
fxslot.lVolume = 0;
|
||||
fxslot.ulFlags = EAXFXSLOTFLAGS_ENVIRONMENT;
|
||||
|
||||
hr = mBufferReverb->Set(guid, EAXFXSLOT_ALLPARAMETERS, NULL, 0, &fxslot, sizeof(EAXFXSLOTPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ULONG ulReceived;
|
||||
GUID effect;
|
||||
|
||||
/*
|
||||
Check if the slot contains a reverb. If so, we can still use that slot.
|
||||
*/
|
||||
hr = mBufferReverb->Get(guid, EAXFXSLOT_LOADEFFECT, NULL, 0, &effect, sizeof(GUID), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
if (memcmp(&effect, &fxslot.guidLoadEffect, sizeof(GUID)))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
gFXslot3set = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
break;
|
||||
}
|
||||
|
||||
eaxprop.ulEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
eaxprop.flEnvironmentSize = prop->EnvSize;
|
||||
eaxprop.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
eaxprop.lRoom = prop->Room;
|
||||
eaxprop.lRoomHF = prop->RoomHF;
|
||||
eaxprop.lRoomLF = prop->RoomLF;
|
||||
eaxprop.flDecayTime = prop->DecayTime;
|
||||
eaxprop.flDecayHFRatio = prop->DecayHFRatio;
|
||||
eaxprop.flDecayLFRatio = prop->DecayLFRatio;
|
||||
eaxprop.lReflections = prop->Reflections;
|
||||
eaxprop.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
eaxprop.vReflectionsPan.x = prop->ReflectionsPan[0];
|
||||
eaxprop.vReflectionsPan.y = prop->ReflectionsPan[1];
|
||||
eaxprop.vReflectionsPan.z = prop->ReflectionsPan[2];
|
||||
eaxprop.lReverb = prop->Reverb;
|
||||
eaxprop.flReverbDelay = prop->ReverbDelay;
|
||||
eaxprop.vReverbPan.x = prop->ReverbPan[0];
|
||||
eaxprop.vReverbPan.y = prop->ReverbPan[1];
|
||||
eaxprop.vReverbPan.z = prop->ReverbPan[2];
|
||||
eaxprop.flEchoTime = prop->EchoTime;
|
||||
eaxprop.flEchoDepth = prop->EchoDepth;
|
||||
eaxprop.flModulationTime = prop->ModulationTime;
|
||||
eaxprop.flModulationDepth = prop->ModulationDepth;
|
||||
eaxprop.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
eaxprop.flHFReference = prop->HFReference;
|
||||
eaxprop.flLFReference = prop->LFReference;
|
||||
eaxprop.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxprop.ulFlags = prop->Flags & 0xFF;
|
||||
|
||||
hr = mBufferReverb->Set(guid, EAXREVERB_ALLPARAMETERS, NULL, 0, &eaxprop, sizeof(EAXREVERBPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::getPropertiesEAX4(FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EAXREVERBPROPERTIES eaxprop;
|
||||
ULONG ulReceived;
|
||||
GUID guid;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch(prop->Instance)
|
||||
{
|
||||
case 1:
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
break;
|
||||
case 2:
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
break;
|
||||
default:
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
break;
|
||||
}
|
||||
|
||||
hr = mBufferReverb->Get(guid, EAXREVERB_ALLPARAMETERS, NULL, 0, &eaxprop, sizeof(EAXREVERBPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Environment = eaxprop.ulEnvironment ;
|
||||
prop->EnvSize = eaxprop.flEnvironmentSize ;
|
||||
prop->EnvDiffusion = eaxprop.flEnvironmentDiffusion ;
|
||||
prop->Room = eaxprop.lRoom ;
|
||||
prop->RoomHF = eaxprop.lRoomHF ;
|
||||
prop->RoomLF = eaxprop.lRoomLF ;
|
||||
prop->DecayTime = eaxprop.flDecayTime ;
|
||||
prop->DecayHFRatio = eaxprop.flDecayHFRatio ;
|
||||
prop->DecayLFRatio = eaxprop.flDecayLFRatio ;
|
||||
prop->Reflections = eaxprop.lReflections ;
|
||||
prop->ReflectionsDelay = eaxprop.flReflectionsDelay ;
|
||||
prop->ReflectionsPan[0] = eaxprop.vReflectionsPan.x ;
|
||||
prop->ReflectionsPan[1] = eaxprop.vReflectionsPan.y ;
|
||||
prop->ReflectionsPan[2] = eaxprop.vReflectionsPan.z ;
|
||||
prop->Reverb = eaxprop.lReverb ;
|
||||
prop->ReverbDelay = eaxprop.flReverbDelay ;
|
||||
prop->ReverbPan[0] = eaxprop.vReverbPan.x ;
|
||||
prop->ReverbPan[1] = eaxprop.vReverbPan.y ;
|
||||
prop->ReverbPan[2] = eaxprop.vReverbPan.z ;
|
||||
prop->EchoTime = eaxprop.flEchoTime ;
|
||||
prop->EchoDepth = eaxprop.flEchoDepth ;
|
||||
prop->ModulationTime = eaxprop.flModulationTime ;
|
||||
prop->ModulationDepth = eaxprop.flModulationDepth ;
|
||||
prop->AirAbsorptionHF = eaxprop.flAirAbsorptionHF ;
|
||||
prop->HFReference = eaxprop.flHFReference ;
|
||||
prop->LFReference = eaxprop.flLFReference ;
|
||||
prop->RoomRolloffFactor = eaxprop.flRoomRolloffFactor ;
|
||||
prop->Flags = eaxprop.ulFlags ;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
|
||||
348
fmod/win32/src/fmod_output_dsound_i3dl2.cpp
Executable file
348
fmod/win32/src/fmod_output_dsound_i3dl2.cpp
Executable file
|
|
@ -0,0 +1,348 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_I3DL2
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_3dl2.h"
|
||||
#include "fmod_localcriticalsection.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_sample_dsound.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::querySupportI3DL2(unsigned int ulQuery)
|
||||
{
|
||||
unsigned long ulSupport = 0;
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportI3DL2", "check properties %08X\n", ulQuery));
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->QuerySupport(guid, ulQuery, &ulSupport);
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (ulSupport&(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET)) ==
|
||||
(KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET) )
|
||||
{
|
||||
mFeaturesReverb |= (DWORD)(1 << ulQuery);
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::querySupportI3DL2", "success\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
bool OutputDSound::initI3DL2()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
ULONG support = 0;
|
||||
HRESULT hr = DS_OK;
|
||||
GUID guid;
|
||||
FMOD_CODEC_WAVEFORMAT waveformat;
|
||||
|
||||
if (mBufferReverb)
|
||||
{
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Create I3DL2 sample
|
||||
*/
|
||||
|
||||
FMOD_memset(&waveformat, 0, sizeof(FMOD_CODEC_WAVEFORMAT));
|
||||
waveformat.frequency = 44100;
|
||||
waveformat.lengthpcm = 1024;
|
||||
waveformat.channels = 1;
|
||||
waveformat.format = FMOD_SOUND_FORMAT_PCM16;
|
||||
|
||||
result = createSample(FMOD_3D | FMOD_UNIQUE, &waveformat, (Sample **)&mSampleReverb);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
OBTAIN I3DL2 INTERFACE TO BUFFER
|
||||
*/
|
||||
FMOD_memcpy(&guid, &FMOD_IID_IKsPropertySet, sizeof(GUID));
|
||||
|
||||
if(mSampleReverb->mBuffer3D->QueryInterface(guid, (void **)&mBufferReverb) != DS_OK)
|
||||
{
|
||||
mBufferReverb = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
QUERY FOR I3DL2 support
|
||||
*/
|
||||
support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_ALL);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_ROOM);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_ROOMHF);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_ROOMROLLOFFFACTOR);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_DECAYTIME);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_DECAYHFRATIO);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_REFLECTIONS);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_REFLECTIONSDELAY);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_REVERB);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_REVERBDELAY);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_DIFFUSION);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_DENSITY);
|
||||
if (support) support = querySupportI3DL2(DSPROPERTY_I3DL2LISTENER_HFREFERENCE);
|
||||
|
||||
if (support)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initI3DL2", "I3DL2 - success\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initI3DL2", "I3DL2 - FAIL\n"));
|
||||
}
|
||||
|
||||
if (!mFeaturesReverb)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::initI3DL2", "failed I3DL2 check, releasing reverb interface\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Turn down reverb to start with.
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ROOM))
|
||||
{
|
||||
DWORD Room = I3DL2LISTENER_MINROOM;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_I3DL2LISTENER_ROOM, 0, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::closeI3DL2()
|
||||
{
|
||||
if (mBufferReverb)
|
||||
{
|
||||
/*
|
||||
Turn down reverb again
|
||||
*/
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ROOM))
|
||||
{
|
||||
GUID guid;
|
||||
DWORD Room = I3DL2LISTENER_MINROOM;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_ListenerProperties, sizeof(GUID));
|
||||
|
||||
mBufferReverb->Set(guid, DSPROPERTY_I3DL2LISTENER_ROOM, 0, 0, &Room, sizeof(DWORD));
|
||||
}
|
||||
|
||||
mBufferReverb->Release();
|
||||
mBufferReverb = 0;
|
||||
}
|
||||
|
||||
if (mSampleReverb)
|
||||
{
|
||||
mSampleReverb->release();
|
||||
mSampleReverb = 0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::setPropertiesI3DL2(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesI3DL2", "Entering \n"));
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ALL) )
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesI3DL2", "failed - apparently DSPROPERTY_I3DL2LISTENER_ALL isnt supported\n"));
|
||||
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ALL)
|
||||
{
|
||||
HRESULT hr;
|
||||
I3DL2_LISTENERPROPERTIES dsprop = {0};
|
||||
GUID guid;
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesI3DL2", "setting listener properties\n"));
|
||||
|
||||
dsprop.lRoom = prop->Room;
|
||||
dsprop.lRoomHF = prop->RoomHF;
|
||||
dsprop.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
dsprop.flDecayTime = prop->DecayTime;
|
||||
dsprop.flDecayHFRatio = prop->DecayHFRatio;
|
||||
dsprop.lReflections = prop->Reflections;
|
||||
dsprop.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
dsprop.lReverb = prop->Reverb;
|
||||
dsprop.flReverbDelay = prop->ReverbDelay;
|
||||
dsprop.flDiffusion = prop->Diffusion;
|
||||
dsprop.flDensity = prop->Density;
|
||||
dsprop.flHFReference = prop->HFReference;
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Set(guid, DSPROPERTY_I3DL2LISTENER_ALL, 0, 0, &dsprop, sizeof(I3DL2_LISTENERPROPERTIES));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ALL, __FILE__, __LINE__, "OutputDSound::setPropertiesEAX2", "setting listener properties FAILED\n"));
|
||||
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::getPropertiesI3DL2(FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
ULONG ulReceived;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ( !(mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ALL) )
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((mFeaturesReverb & (DWORD)1 << DSPROPERTY_I3DL2LISTENER_ALL))
|
||||
{
|
||||
GUID guid;
|
||||
HRESULT hr;
|
||||
I3DL2_LISTENERPROPERTIES dsprop = {0};
|
||||
|
||||
FMOD_memcpy(&guid, &FMOD_DSPROPSETID_I3DL2_ListenerProperties, sizeof(GUID));
|
||||
|
||||
hr = mBufferReverb->Get(guid, DSPROPERTY_I3DL2LISTENER_ALL, 0, 0, &dsprop, sizeof(I3DL2_LISTENERPROPERTIES), &ulReceived);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FMOD_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
prop->Environment = 0;
|
||||
prop->EnvSize = 0;
|
||||
prop->EnvDiffusion = 0;
|
||||
prop->Room = dsprop.lRoom;
|
||||
prop->RoomHF = dsprop.lRoomHF;
|
||||
prop->RoomLF = 0;
|
||||
prop->DecayTime = dsprop.flDecayTime;
|
||||
prop->DecayHFRatio = dsprop.flDecayHFRatio;
|
||||
prop->DecayLFRatio = 0;
|
||||
prop->Reflections = dsprop.lReflections;
|
||||
prop->ReflectionsDelay = dsprop.flReflectionsDelay;
|
||||
prop->ReflectionsPan[0] = 0;
|
||||
prop->ReflectionsPan[1] = 0;
|
||||
prop->ReflectionsPan[2] = 0;
|
||||
prop->Reverb = dsprop.lReverb;
|
||||
prop->ReverbDelay = dsprop.flReverbDelay;
|
||||
prop->ReverbPan[0] = 0;
|
||||
prop->ReverbPan[1] = 0;
|
||||
prop->ReverbPan[2] = 0;
|
||||
prop->EchoTime = 0;
|
||||
prop->EchoDepth = 0;
|
||||
prop->ModulationTime = 0;
|
||||
prop->ModulationDepth = 0;
|
||||
prop->AirAbsorptionHF = 0;
|
||||
prop->HFReference = dsprop.flHFReference;
|
||||
prop->LFReference = 0;
|
||||
prop->RoomRolloffFactor = dsprop.flRoomRolloffFactor;
|
||||
prop->Flags = 0;
|
||||
prop->Density = dsprop.flDensity;
|
||||
prop->Diffusion = dsprop.flDiffusion;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_I3DL2 */
|
||||
546
fmod/win32/src/fmod_output_dsound_record.cpp
Executable file
546
fmod/win32/src/fmod_output_dsound_record.cpp
Executable file
|
|
@ -0,0 +1,546 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#if defined(FMOD_SUPPORT_DSOUND) && defined(FMOD_SUPPORT_RECORDING)
|
||||
|
||||
#include "fmod.hpp"
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_soundi.h"
|
||||
#include "fmod_stringw.h"
|
||||
#include "fmod_codec_wav.h"
|
||||
|
||||
#include <dxsdkver.h>
|
||||
#if (_DXSDK_PRODUCT_MAJOR < 9 || (_DXSDK_PRODUCT_MAJOR == 9 && _DXSDK_PRODUCT_MINOR < 21))
|
||||
#include <dplay.h> /* This defines DWORD_PTR for dsound.h to use. */
|
||||
#endif
|
||||
#include <dsound.h>
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
static const FMOD_GUID KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71} };
|
||||
static const FMOD_GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71} };
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Callback to enumerate each found input driver
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
The first enumerated driver is skipped as it has no GUID, (it's a duplicate
|
||||
anyway), the next driver enumerated is always the default, therefore it will be
|
||||
in element 0 of FMODs driver list as required.
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
BOOL CALLBACK FMOD_Output_DSound_RecordEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCWSTR lpszDrvName, LPVOID lpContext)
|
||||
{
|
||||
FMOD::OutputDSound *outputdsound = (FMOD::OutputDSound *)lpContext;
|
||||
|
||||
// Don't allow more drivers than the maximum number of drivers
|
||||
if (outputdsound->mRecordNumDrivers < FMOD_OUTPUT_MAXDRIVERS)
|
||||
{
|
||||
// Don't add pseudo driver "Primary..." (no GUID), it is just a dupe anyway
|
||||
if (lpGUID)
|
||||
{
|
||||
outputdsound->mRecordDriverName[outputdsound->mRecordNumDrivers] = (short *)FMOD_Memory_Calloc((FMOD_strlenW((short *)lpszDesc) + 1) * sizeof(short));
|
||||
if (outputdsound->mRecordDriverName[outputdsound->mRecordNumDrivers])
|
||||
{
|
||||
FMOD_strncpyW(outputdsound->mRecordDriverName[outputdsound->mRecordNumDrivers], (short *)lpszDesc, FMOD_strlenW((short *)lpszDesc));
|
||||
}
|
||||
|
||||
FMOD_memcpy(&outputdsound->mRecordGUID[outputdsound->mRecordNumDrivers], lpGUID, sizeof(GUID));
|
||||
|
||||
{
|
||||
short driverName[FMOD_STRING_MAXNAMELEN] = {0};
|
||||
|
||||
FMOD_strncpyW(driverName, (short *)lpszDesc, FMOD_STRING_MAXNAMELEN);
|
||||
FMOD_wtoa(driverName);
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "FMOD_Output_DSound_RecordEnumProc", "Enumerating \"%s\"\n", driverName));
|
||||
}
|
||||
|
||||
outputdsound->mRecordNumDrivers++;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordEnumerate()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
if (mRecordEnumerated)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
result = registerDLL();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mRecordNumDrivers; i++)
|
||||
{
|
||||
if (mRecordDriverName[i])
|
||||
{
|
||||
FMOD_Memory_Free(mRecordDriverName[i]);
|
||||
mRecordDriverName[i] = NULL;
|
||||
}
|
||||
}
|
||||
mRecordNumDrivers = 0;
|
||||
|
||||
if (mDirectSoundCaptureEnumerate)
|
||||
{
|
||||
(*mDirectSoundCaptureEnumerate)((LPDSENUMCALLBACKW)FMOD_Output_DSound_RecordEnumProc, (void *)this);
|
||||
}
|
||||
|
||||
mRecordEnumerated = true;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordGetNumDrivers(int *numdrivers)
|
||||
{
|
||||
if (!numdrivers)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (!mRecordEnumerated)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = recordEnumerate();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
*numdrivers = mRecordNumDrivers;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordGetDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid)
|
||||
{
|
||||
if (!mRecordEnumerated)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = recordEnumerate();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (id < 0 || id >= mRecordNumDrivers)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (name && namelen >= 1)
|
||||
{
|
||||
short driverName[FMOD_STRING_MAXNAMELEN] = {0};
|
||||
|
||||
FMOD_strncpyW(driverName, mRecordDriverName[id], FMOD_STRING_MAXNAMELEN - 1);
|
||||
FMOD_wtoa(driverName);
|
||||
|
||||
FMOD_strncpy(name, (char *)driverName, namelen - 1);
|
||||
name[namelen - 1] = 0;
|
||||
}
|
||||
|
||||
if (guid)
|
||||
{
|
||||
FMOD_memcpy(guid, &mRecordGUID[id], sizeof(FMOD_GUID));
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordGetDriverInfoW(int id, short *name, int namelen, FMOD_GUID *guid)
|
||||
{
|
||||
if (!mRecordEnumerated)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = recordEnumerate();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (id < 0 || id >= mRecordNumDrivers)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (name && namelen >= 1)
|
||||
{
|
||||
FMOD_strncpyW(name, mRecordDriverName[id], namelen - 1);
|
||||
name[namelen - 1] = 0;
|
||||
}
|
||||
|
||||
if (guid)
|
||||
{
|
||||
FMOD_memcpy(guid, &mRecordGUID[id], sizeof(FMOD_GUID));
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordStart(FMOD_RECORDING_INFO *recordinfo, Sound *sound, bool loop)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
DSCBUFFERDESC dscbd;
|
||||
WAVE_FORMATEXTENSIBLE wfx;
|
||||
SoundI *soundi;
|
||||
int bits;
|
||||
HRESULT hr;
|
||||
FMOD_DSoundRecordMembers *recordMembers = NULL;
|
||||
|
||||
soundi = (SoundI *)sound;
|
||||
if (!soundi)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
result = registerDLL();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!mDirectSoundCaptureCreate)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
recordinfo->mRecordPlatformSpecific = recordMembers = (FMOD_DSoundRecordMembers *)FMOD_Object_Calloc(FMOD_DSoundRecordMembers);
|
||||
if (recordMembers == NULL)
|
||||
{
|
||||
return FMOD_ERR_MEMORY;
|
||||
}
|
||||
|
||||
// ========================================================================================================
|
||||
// CREATE CAPTURE SYSTEM
|
||||
// ========================================================================================================
|
||||
hr = (*mDirectSoundCaptureCreate)(&mRecordGUID[recordinfo->mRecordId], &recordMembers->mDirectSoundCapture, 0);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
// ========================================================================================================
|
||||
// CREATE AND START CAPTURE BUFFER
|
||||
// ========================================================================================================
|
||||
recordinfo->mRecordFormat = soundi->mFormat;
|
||||
recordinfo->mRecordChannels = soundi->mChannels;
|
||||
recordinfo->mRecordBufferLength = soundi->mLength;
|
||||
recordinfo->mRecordRate = (int)soundi->mDefaultFrequency;
|
||||
|
||||
SoundI::getBitsFromFormat(recordinfo->mRecordFormat, &bits);
|
||||
|
||||
FMOD_memset(&wfx, 0, sizeof(WAVE_FORMATEXTENSIBLE));
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
wfx.Format.nChannels = recordinfo->mRecordChannels;
|
||||
wfx.Format.wBitsPerSample = bits;
|
||||
wfx.Format.nBlockAlign = wfx.Format.nChannels * wfx.Format.wBitsPerSample / 8;
|
||||
wfx.Format.nSamplesPerSec = recordinfo->mRecordRate;
|
||||
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
|
||||
wfx.Format.cbSize = 22; // Designates extra data
|
||||
wfx.Samples.wValidBitsPerSample = bits;
|
||||
FMOD_memcpy(&wfx.SubFormat, (soundi->mFormat == FMOD_SOUND_FORMAT_PCMFLOAT ? &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : &KSDATAFORMAT_SUBTYPE_PCM), sizeof(GUID));
|
||||
|
||||
dscbd.dwSize = sizeof(DSCBUFFERDESC);
|
||||
dscbd.dwFlags = 0;
|
||||
dscbd.dwBufferBytes = recordinfo->mRecordBufferLength * wfx.Format.nBlockAlign;
|
||||
dscbd.dwReserved = 0;
|
||||
dscbd.lpwfxFormat = (WAVEFORMATEX*)&wfx;
|
||||
dscbd.dwFXCount = 0;
|
||||
dscbd.lpDSCFXDesc = 0;
|
||||
|
||||
hr = recordMembers->mDirectSoundCapture->CreateCaptureBuffer(&dscbd, &recordMembers->mDirectSoundCaptureBuffer, 0);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_FORMAT;
|
||||
}
|
||||
|
||||
hr = recordMembers->mDirectSoundCaptureBuffer->Start(loop);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordStop(FMOD_RECORDING_INFO *recordinfo)
|
||||
{
|
||||
FMOD_DSoundRecordMembers *recordMembers = (FMOD_DSoundRecordMembers *)recordinfo->mRecordPlatformSpecific;
|
||||
|
||||
if (recordinfo)
|
||||
{
|
||||
if (recordMembers->mDirectSoundCaptureBuffer)
|
||||
{
|
||||
recordMembers->mDirectSoundCaptureBuffer->Stop();
|
||||
recordMembers->mDirectSoundCaptureBuffer->Release();
|
||||
recordMembers->mDirectSoundCaptureBuffer = 0;
|
||||
}
|
||||
|
||||
if (recordMembers->mDirectSoundCapture)
|
||||
{
|
||||
recordMembers->mDirectSoundCapture->Release();
|
||||
recordMembers->mDirectSoundCapture = 0;
|
||||
}
|
||||
|
||||
FMOD_Memory_Free(recordinfo->mRecordPlatformSpecific);
|
||||
recordinfo->mRecordPlatformSpecific = 0;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordGetPosition(FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
HRESULT hr = DS_OK;
|
||||
unsigned int position = 0, lengthbytes;
|
||||
FMOD_SOUND_FORMAT format;
|
||||
int bits, channels;
|
||||
FMOD_DSoundRecordMembers *recordMembers = (FMOD_DSoundRecordMembers *)recordinfo->mRecordPlatformSpecific;
|
||||
|
||||
if (!recordMembers->mDirectSoundCaptureBuffer)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
hr = recordMembers->mDirectSoundCaptureBuffer->GetCurrentPosition(0, (LPDWORD)&position);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
result = recordinfo->mRecordSound->getLength(&lengthbytes, FMOD_TIMEUNIT_PCMBYTES);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = recordinfo->mRecordSound->getFormat(0, &format, &channels, &bits);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (position >= lengthbytes)
|
||||
{
|
||||
*pcm = 0;
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;;
|
||||
}
|
||||
|
||||
position *= 8;
|
||||
position /= bits;
|
||||
position /= channels;
|
||||
|
||||
if (pcm)
|
||||
{
|
||||
*pcm = position;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordLock(FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2)
|
||||
{
|
||||
FMOD_DSoundRecordMembers *recordMembers = (FMOD_DSoundRecordMembers *)recordinfo->mRecordPlatformSpecific;
|
||||
|
||||
recordMembers->mDirectSoundCaptureBuffer->Lock(offset, length, ptr1, (DWORD *)len1, ptr2, (DWORD *)len2, 0);
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputDSound::recordUnlock(FMOD_RECORDING_INFO *recordinfo, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2)
|
||||
{
|
||||
FMOD_DSoundRecordMembers *recordMembers = (FMOD_DSoundRecordMembers *)recordinfo->mRecordPlatformSpecific;
|
||||
|
||||
recordMembers->mDirectSoundCaptureBuffer->Unlock(ptr1, len1, ptr2, len2);
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
2224
fmod/win32/src/fmod_output_openal.cpp
Executable file
2224
fmod/win32/src/fmod_output_openal.cpp
Executable file
File diff suppressed because it is too large
Load diff
132
fmod/win32/src/fmod_output_openal.h
Executable file
132
fmod/win32/src/fmod_output_openal.h
Executable file
|
|
@ -0,0 +1,132 @@
|
|||
#ifndef _FMOD_OUTPUT_OPENAL_H
|
||||
#define _FMOD_OUTPUT_OPENAL_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
|
||||
#include "fmod_systemi.h"
|
||||
#include "fmod_output_timer.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
|
||||
#include "../../lib/openal/utils/LoadOAL.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
|
||||
typedef ALboolean (*EAXSetBufferMode)(ALsizei n, ALuint *buffers, ALint value);
|
||||
typedef ALenum (*EAXGetBufferMode)(ALuint buffer, ALint *value);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool used;
|
||||
ALuint sid;
|
||||
ALuint *bid;
|
||||
} SourceOpenAL;
|
||||
|
||||
class OutputOpenAL : public OutputTimer
|
||||
{
|
||||
friend class SampleOpenAL;
|
||||
friend class ChannelOpenAL;
|
||||
friend class ChannelOpenALEAX2;
|
||||
friend class ChannelOpenALEAX3;
|
||||
friend class ChannelOpenALEAX4;
|
||||
friend class ChannelOpenALEAX5;
|
||||
|
||||
private:
|
||||
|
||||
OPENALFNTABLE mOALFnTable;
|
||||
bool mSetupOnce;
|
||||
bool mInitialised;
|
||||
bool mDLLInitialised;
|
||||
|
||||
ALCdevice *mDevice;
|
||||
ALCcontext *mContext;
|
||||
int mNumDrivers;
|
||||
char *mDriverNames[FMOD_OUTPUT_MAXDRIVERS];
|
||||
int mNumBuffers;
|
||||
unsigned int mBufferLength;
|
||||
unsigned int mBufferLengthBytes;
|
||||
unsigned int mPcmBase;
|
||||
char *mBufferData;
|
||||
int mNumChannels;
|
||||
ChannelOpenAL *mChannels;
|
||||
int mNumSources;
|
||||
SourceOpenAL *mSources;
|
||||
unsigned int mMixerSourceOffset;
|
||||
|
||||
int mRate;
|
||||
FMOD_SOUND_FORMAT mFormat;
|
||||
ALuint mFormatOAL;
|
||||
int mNumHwChannels;
|
||||
int mOutputChannels;
|
||||
REVERB_VERSION mReverbVersion;
|
||||
bool mMixerReverbDisabled;
|
||||
|
||||
EAXSet mEAXSet;
|
||||
EAXGet mEAXGet;
|
||||
EAXSetBufferMode mEAXSetBufferMode;
|
||||
EAXGetBufferMode mEAXGetBufferMode;
|
||||
|
||||
// Private methods
|
||||
FMOD_RESULT registerDLL ();
|
||||
FMOD_RESULT enumerate ();
|
||||
FMOD_RESULT initEAX ();
|
||||
FMOD_RESULT setupSessionEAX5 ();
|
||||
FMOD_RESULT getSpeakerModeEAX5 (FMOD_SPEAKERMODE *speakerMode);
|
||||
FMOD_RESULT lockSlotEAX4 (GUID &slotGUID);
|
||||
FMOD_RESULT lockSlotEAX5 (GUID &slotGUID);
|
||||
FMOD_RESULT setPropertiesEAX2 (const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT setPropertiesEAX3 (const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT setPropertiesEAX4 (const FMOD_REVERB_PROPERTIES *prop);
|
||||
FMOD_RESULT setPropertiesEAX5 (const FMOD_REVERB_PROPERTIES *prop);
|
||||
|
||||
public:
|
||||
|
||||
OutputOpenAL();
|
||||
static FMOD_OUTPUT_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
// Public methods
|
||||
FMOD_RESULT getFreeChannel (FMOD_MODE mode, ChannelReal **realchannel, int numchannels, int numsoundchannels, int *found);
|
||||
FMOD_RESULT getNumDrivers (int *numdrivers);
|
||||
FMOD_RESULT getDriverName (int id, char *name, int namelen);
|
||||
FMOD_RESULT getDriverCapsEx (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode, int *num2dchannels, int *num3dchannels, int *totalchannels);
|
||||
FMOD_RESULT init (int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
|
||||
FMOD_RESULT close ();
|
||||
FMOD_RESULT start ();
|
||||
FMOD_RESULT stop ();
|
||||
FMOD_RESULT getHandle (void **handle);
|
||||
FMOD_RESULT update ();
|
||||
FMOD_RESULT postMix ();
|
||||
FMOD_RESULT getPosition (unsigned int *pcm);
|
||||
FMOD_RESULT lock (unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT unlock (void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
FMOD_RESULT createSample (FMOD_MODE mode, FMOD_CODEC_WAVEFORMAT *waveformat, Sample **sample);
|
||||
FMOD_RESULT setReverbProperties (const FMOD_REVERB_PROPERTIES *prop);
|
||||
int getSampleMaxChannels (FMOD_MODE mode, FMOD_SOUND_FORMAT format);
|
||||
|
||||
// Public callbacks
|
||||
static FMOD_RESULT F_CALLBACK getNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK getDriverNameCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen);
|
||||
static FMOD_RESULT F_CALLBACK getDriverCapsExCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode, int *num2dchannels, int *num3dchannels, int *totalchannels);
|
||||
static FMOD_RESULT F_CALLBACK initCallback (FMOD_OUTPUT_STATE *output, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK startCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK stopCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getHandleCallback (FMOD_OUTPUT_STATE *output, void **handle);
|
||||
static FMOD_RESULT F_CALLBACK updateCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK postMixCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getPositionCallback (FMOD_OUTPUT_STATE *output, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK lockCallback (FMOD_OUTPUT_STATE *output, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
static FMOD_RESULT F_CALLBACK unlockCallback (FMOD_OUTPUT_STATE *output, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
static FMOD_RESULT F_CALLBACK createSampleCallback (FMOD_OUTPUT_STATE *output, FMOD_MODE mode, FMOD_CODEC_WAVEFORMAT *waveformat, Sample **sample);
|
||||
static FMOD_RESULT F_CALLBACK setReverbPropertiesCallback (FMOD_OUTPUT_STATE *output, const FMOD_REVERB_PROPERTIES *prop);
|
||||
static int F_CALLBACK getSampleMaxChannelsCallback (FMOD_OUTPUT_STATE *output, FMOD_MODE mode, FMOD_SOUND_FORMAT format);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* #ifdef FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif /* #ifndef _FMOD_OUTPUT_OPENAL_H */
|
||||
95
fmod/win32/src/fmod_output_openal_eax2.cpp
Executable file
95
fmod/win32/src/fmod_output_openal_eax2.cpp
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_eax2.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set properties for EAX2
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::setPropertiesEAX2(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
GUID bufferGUID;
|
||||
GUID listenerGUID;
|
||||
EAXLISTENERPROPERTIES eaxProperties;
|
||||
int room;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX2", "Setting reverb properties\n"));
|
||||
|
||||
/*
|
||||
Make sure all reverb effects are disabled on the mixer sources
|
||||
*/
|
||||
if (!mMixerReverbDisabled)
|
||||
{
|
||||
room = -10000;
|
||||
FMOD_memcpy(&bufferGUID, &FMOD_DSPROPSETID_EAX20_BufferProperties, sizeof(GUID));
|
||||
|
||||
// Only the first mixer source is technically used (multichannel source), but set all anyway
|
||||
for (int i = mMixerSourceOffset; i < mNumSources; i++)
|
||||
{
|
||||
mEAXSet(&bufferGUID, DSPROPERTY_EAXBUFFER_ROOM, mSources[i].sid, &room, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mMixerReverbDisabled = true;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&listenerGUID, &FMOD_DSPROPSETID_EAX20_ListenerProperties, sizeof(GUID));
|
||||
|
||||
eaxProperties.flEnvironmentSize = prop->EnvSize;
|
||||
eaxProperties.dwEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
eaxProperties.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
eaxProperties.lRoom = prop->Room;
|
||||
eaxProperties.lRoomHF = prop->RoomHF;
|
||||
eaxProperties.flDecayTime = prop->DecayTime;
|
||||
eaxProperties.flDecayHFRatio = prop->DecayHFRatio;
|
||||
eaxProperties.lReflections = prop->Reflections;
|
||||
eaxProperties.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
eaxProperties.lReverb = prop->Reverb;
|
||||
eaxProperties.flReverbDelay = prop->ReverbDelay;
|
||||
eaxProperties.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
eaxProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxProperties.dwFlags = prop->Flags & 0xFF; // Mask out FMOD specific flags, leaving only EAX flags
|
||||
|
||||
mEAXSet(&listenerGUID, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, 0, &eaxProperties, sizeof(EAXLISTENERPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX2", "Error setting reverb properties\n"));
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
} /* namespace FMOD */
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
109
fmod/win32/src/fmod_output_openal_eax3.cpp
Executable file
109
fmod/win32/src/fmod_output_openal_eax3.cpp
Executable file
|
|
@ -0,0 +1,109 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_eax3.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set properties for EAX3
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::setPropertiesEAX3(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
GUID bufferGUID;
|
||||
GUID listenerGUID;
|
||||
EAXLISTENERPROPERTIES eaxProperties;
|
||||
int room;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX3", "Setting reverb properties\n"));
|
||||
|
||||
/*
|
||||
Make sure all reverb effects are disabled on the mixer sources
|
||||
*/
|
||||
if (!mMixerReverbDisabled)
|
||||
{
|
||||
room = -10000;
|
||||
FMOD_memcpy(&bufferGUID, &FMOD_DSPROPSETID_EAX30_BufferProperties, sizeof(GUID));
|
||||
|
||||
// Only the first mixer source is technically used (multichannel source), but set all anyway
|
||||
for (int i = mMixerSourceOffset; i < mNumSources; i++)
|
||||
{
|
||||
mEAXSet(&bufferGUID, DSPROPERTY_EAXBUFFER_ROOM, mSources[i].sid, &room, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mMixerReverbDisabled = true;
|
||||
}
|
||||
|
||||
FMOD_memcpy(&listenerGUID, &FMOD_DSPROPSETID_EAX30_ListenerProperties, sizeof(GUID));
|
||||
|
||||
eaxProperties.ulEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
eaxProperties.flEnvironmentSize = prop->EnvSize;
|
||||
eaxProperties.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
eaxProperties.lRoom = prop->Room;
|
||||
eaxProperties.lRoomHF = prop->RoomHF;
|
||||
eaxProperties.lRoomLF = prop->RoomLF;
|
||||
eaxProperties.flDecayTime = prop->DecayTime;
|
||||
eaxProperties.flDecayHFRatio = prop->DecayHFRatio;
|
||||
eaxProperties.flDecayLFRatio = prop->DecayLFRatio;
|
||||
eaxProperties.lReflections = prop->Reflections;
|
||||
eaxProperties.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
eaxProperties.vReflectionsPan.x = prop->ReflectionsPan[0];
|
||||
eaxProperties.vReflectionsPan.y = prop->ReflectionsPan[1];
|
||||
eaxProperties.vReflectionsPan.z = prop->ReflectionsPan[2];
|
||||
eaxProperties.lReverb = prop->Reverb;
|
||||
eaxProperties.flReverbDelay = prop->ReverbDelay;
|
||||
eaxProperties.vReverbPan.x = prop->ReverbPan[0];
|
||||
eaxProperties.vReverbPan.y = prop->ReverbPan[1];
|
||||
eaxProperties.vReverbPan.z = prop->ReverbPan[2];
|
||||
eaxProperties.flEchoTime = prop->EchoTime;
|
||||
eaxProperties.flEchoDepth = prop->EchoDepth;
|
||||
eaxProperties.flModulationTime = prop->ModulationTime;
|
||||
eaxProperties.flModulationDepth = prop->ModulationDepth;
|
||||
eaxProperties.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
eaxProperties.flHFReference = prop->HFReference;
|
||||
eaxProperties.flLFReference = prop->LFReference;
|
||||
eaxProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxProperties.ulFlags = prop->Flags & 0xFF; // Mask out FMOD specific flags, leaving only EAX flags
|
||||
|
||||
mEAXSet(&listenerGUID, DSPROPERTY_EAXLISTENER_ALLPARAMETERS, 0, &eaxProperties, sizeof(EAXLISTENERPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX3", "Error setting reverb properties\n"));
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
} /* namespace FMOD */
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
225
fmod/win32/src/fmod_output_openal_eax4.cpp
Executable file
225
fmod/win32/src/fmod_output_openal_eax4.cpp
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_eax4.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
bool gEAX4LockedOALFxSlot2 = false;
|
||||
bool gEAX4LockedOALFxSlot3 = false;
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Attempt to lock an EAX slot
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::lockSlotEAX4(GUID &slotGUID)
|
||||
{
|
||||
int slotIsLocked;
|
||||
EAXFXSLOTPROPERTIES fxSlot;
|
||||
|
||||
FMOD_memcpy(&fxSlot.guidLoadEffect, &FMOD_EAX_REVERB_EFFECT, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Check if this slot is locked
|
||||
*/
|
||||
mEAXGet(&slotGUID, EAXFXSLOT_LOCK, 0, &slotIsLocked, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
if (slotIsLocked)
|
||||
{
|
||||
GUID effect;
|
||||
|
||||
// Find out what type of effect is in the locked slot
|
||||
mEAXGet(&slotGUID, EAXFXSLOT_LOADEFFECT, 0, &effect, sizeof(GUID));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
// Check if the slot contains a reverb, if so we can still use that slot
|
||||
if (memcmp(&effect, &fxSlot.guidLoadEffect, sizeof(GUID)))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
else // Slot isn't locked
|
||||
{
|
||||
fxSlot.lLock = EAXFXSLOT_LOCKED;
|
||||
fxSlot.lVolume = EAXFXSLOT_DEFAULTVOLUME;
|
||||
fxSlot.ulFlags = EAXFXSLOT_DEFAULTFLAGS;
|
||||
|
||||
// Lock the slot
|
||||
mEAXSet(&slotGUID, EAXFXSLOT_ALLPARAMETERS, 0, &fxSlot, sizeof(EAXFXSLOTPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set properties for EAX4
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
With EAX4 the first slot is locked as reverb so we can still use it,
|
||||
the second slot is locked as chorus, so it is no use to us, slots
|
||||
3 and 4 are free to be tasked as reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::setPropertiesEAX4(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
GUID slotGUID;
|
||||
GUID sourceGUID;
|
||||
EAXREVERBPROPERTIES eaxProperties;
|
||||
FMOD_RESULT result;
|
||||
int room;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX4", "Setting reverb properties for instance: %d\n", prop->Instance));
|
||||
|
||||
/*
|
||||
Make sure all reverb effects are disabled on the mixer sources
|
||||
*/
|
||||
if (!mMixerReverbDisabled)
|
||||
{
|
||||
room = -10000;
|
||||
FMOD_memcpy(&sourceGUID, &FMOD_EAXPROPERTYID_EAX40_Source, sizeof(GUID));
|
||||
|
||||
// Only the first mixer source is technically used (multichannel source), but set all anyway
|
||||
for (int i = mMixerSourceOffset; i < mNumSources; i++)
|
||||
{
|
||||
mEAXSet(&sourceGUID, EAXSOURCE_ROOM, mSources[i].sid, &room, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mMixerReverbDisabled = true;
|
||||
}
|
||||
|
||||
/*
|
||||
Each reverb instance is equivalent to a hardware effect slot,
|
||||
attempt to lock that slot for use by FMOD
|
||||
*/
|
||||
switch (prop->Instance)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX40_FXSlot2, sizeof(GUID));
|
||||
if (!gEAX4LockedOALFxSlot2)
|
||||
{
|
||||
result = lockSlotEAX4(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX4LockedOALFxSlot2 = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX40_FXSlot3, sizeof(GUID));
|
||||
if (!gEAX4LockedOALFxSlot3)
|
||||
{
|
||||
result = lockSlotEAX4(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX4LockedOALFxSlot3 = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX40_FXSlot0, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
|
||||
eaxProperties.ulEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
eaxProperties.flEnvironmentSize = prop->EnvSize;
|
||||
eaxProperties.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
eaxProperties.lRoom = prop->Room;
|
||||
eaxProperties.lRoomHF = prop->RoomHF;
|
||||
eaxProperties.lRoomLF = prop->RoomLF;
|
||||
eaxProperties.flDecayTime = prop->DecayTime;
|
||||
eaxProperties.flDecayHFRatio = prop->DecayHFRatio;
|
||||
eaxProperties.flDecayLFRatio = prop->DecayLFRatio;
|
||||
eaxProperties.lReflections = prop->Reflections;
|
||||
eaxProperties.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
eaxProperties.vReflectionsPan.x = prop->ReflectionsPan[0];
|
||||
eaxProperties.vReflectionsPan.y = prop->ReflectionsPan[1];
|
||||
eaxProperties.vReflectionsPan.z = prop->ReflectionsPan[2];
|
||||
eaxProperties.lReverb = prop->Reverb;
|
||||
eaxProperties.flReverbDelay = prop->ReverbDelay;
|
||||
eaxProperties.vReverbPan.x = prop->ReverbPan[0];
|
||||
eaxProperties.vReverbPan.y = prop->ReverbPan[1];
|
||||
eaxProperties.vReverbPan.z = prop->ReverbPan[2];
|
||||
eaxProperties.flEchoTime = prop->EchoTime;
|
||||
eaxProperties.flEchoDepth = prop->EchoDepth;
|
||||
eaxProperties.flModulationTime = prop->ModulationTime;
|
||||
eaxProperties.flModulationDepth = prop->ModulationDepth;
|
||||
eaxProperties.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
eaxProperties.flHFReference = prop->HFReference;
|
||||
eaxProperties.flLFReference = prop->LFReference;
|
||||
eaxProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxProperties.ulFlags = prop->Flags & 0xFF; // Mask out FMOD specific flags, leaving only EAX flags
|
||||
|
||||
mEAXSet(&slotGUID, EAXREVERB_ALLPARAMETERS, 0, &eaxProperties, sizeof(EAXREVERBPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX4", "Error setting reverb properties\n"));
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
} /* namespace FMOD */
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
386
fmod/win32/src/fmod_output_openal_eax5.cpp
Executable file
386
fmod/win32/src/fmod_output_openal_eax5.cpp
Executable file
|
|
@ -0,0 +1,386 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
#ifdef FMOD_SUPPORT_EAX
|
||||
|
||||
#include "fmod_output_openal.h"
|
||||
#include "fmod_eax5.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
bool gEAX5LockedOALFxSlot0 = false;
|
||||
bool gEAX5LockedOALFxSlot1 = false;
|
||||
bool gEAX5LockedOALFxSlot2 = false;
|
||||
bool gEAX5LockedOALFxSlot3 = false;
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Create an EAX5 session
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
A session must be created before using EAX5
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::setupSessionEAX5()
|
||||
{
|
||||
GUID guid;
|
||||
EAXSESSIONPROPERTIES eaxSession;
|
||||
|
||||
eaxSession.ulEAXVersion = EAX_50;
|
||||
eaxSession.ulMaxActiveSends = 2;
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX50_Context, sizeof(GUID));
|
||||
|
||||
mEAXSet(&guid, EAXCONTEXT_EAXSESSION, 0, &eaxSession, sizeof(EAXSESSIONPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Get the current speaker mode
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
This is called from getCaps, before the main device has been initialised
|
||||
so we need to do EAX5 specific initialisation here for the temporary
|
||||
device
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::getSpeakerModeEAX5(FMOD_SPEAKERMODE *speakerMode)
|
||||
{
|
||||
EAXGet eaxGet = NULL;
|
||||
EAXSet eaxSet = NULL;
|
||||
long oalSpeakerMode = 0;
|
||||
GUID guid;
|
||||
EAXSESSIONPROPERTIES eaxSession;
|
||||
|
||||
/*
|
||||
Get the EAX function pointers
|
||||
*/
|
||||
eaxGet = (EAXGet)mOALFnTable.alGetProcAddress("EAXGet");
|
||||
eaxSet = (EAXSet)mOALFnTable.alGetProcAddress("EAXSet");
|
||||
if (!eaxGet || !eaxSet)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
/*
|
||||
Create an EAX5 session here for the getCaps temporary OAL context
|
||||
*/
|
||||
eaxSession.ulEAXVersion = EAX_50;
|
||||
eaxSession.ulMaxActiveSends = 2;
|
||||
FMOD_memcpy(&guid, &FMOD_EAXPROPERTYID_EAX50_Context, sizeof(GUID));
|
||||
|
||||
eaxSet(&guid, EAXCONTEXT_EAXSESSION, 0, &eaxSession, sizeof(EAXSESSIONPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
/*
|
||||
Determine the speaker mode
|
||||
*/
|
||||
eaxGet(&guid, EAXCONTEXT_SPEAKERCONFIG, 0, &oalSpeakerMode, sizeof(long));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
switch (oalSpeakerMode)
|
||||
{
|
||||
case HEADPHONES:
|
||||
case SPEAKERS_2:
|
||||
{
|
||||
*speakerMode = FMOD_SPEAKERMODE_STEREO;
|
||||
break;
|
||||
}
|
||||
case SPEAKERS_4:
|
||||
{
|
||||
*speakerMode = FMOD_SPEAKERMODE_QUAD;
|
||||
break;
|
||||
}
|
||||
case SPEAKERS_5:
|
||||
{
|
||||
*speakerMode = FMOD_SPEAKERMODE_5POINT1;
|
||||
break;
|
||||
}
|
||||
case SPEAKERS_6:
|
||||
{
|
||||
*speakerMode = FMOD_SPEAKERMODE_RAW;
|
||||
break;
|
||||
}
|
||||
case SPEAKERS_7:
|
||||
{
|
||||
*speakerMode = FMOD_SPEAKERMODE_7POINT1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Attempt to lock an EAX slot
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::lockSlotEAX5(GUID &slotGUID)
|
||||
{
|
||||
int slotIsLocked;
|
||||
EAXFXSLOTPROPERTIES fxSlot;
|
||||
|
||||
FMOD_memcpy(&fxSlot.guidLoadEffect, &FMOD_EAX_REVERB_EFFECT, sizeof(GUID));
|
||||
|
||||
/*
|
||||
Check if this slot is locked
|
||||
*/
|
||||
mEAXGet(&slotGUID, EAXFXSLOT_LOCK, 0, &slotIsLocked, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
if (slotIsLocked)
|
||||
{
|
||||
GUID effect;
|
||||
|
||||
// Find out what type of effect is in the locked slot
|
||||
mEAXGet(&slotGUID, EAXFXSLOT_LOADEFFECT, 0, &effect, sizeof(GUID));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
|
||||
// Check if the slot contains a reverb, if so we can still use that slot
|
||||
if (memcmp(&effect, &fxSlot.guidLoadEffect, sizeof(GUID)))
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
else // Slot isn't locked
|
||||
{
|
||||
fxSlot.lLock = EAXFXSLOT_LOCKED;
|
||||
fxSlot.lVolume = EAXFXSLOT_DEFAULTVOLUME;
|
||||
fxSlot.ulFlags = EAXFXSLOT_DEFAULTFLAGS;
|
||||
fxSlot.lOcclusion = EAXFXSLOT_DEFAULTOCCLUSION;
|
||||
fxSlot.flOcclusionLFRatio = EAXFXSLOT_DEFAULTOCCLUSIONLFRATIO;
|
||||
|
||||
// Lock the slot
|
||||
mEAXSet(&slotGUID, EAXFXSLOT_ALLPARAMETERS, 0, &fxSlot, sizeof(EAXFXSLOTPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_REVERB_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
Set properties for EAX5
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
With EAX5 all four slots can be locked with reverb
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputOpenAL::setPropertiesEAX5(const FMOD_REVERB_PROPERTIES *prop)
|
||||
{
|
||||
GUID slotGUID;
|
||||
GUID sourceGUID;
|
||||
EAXREVERBPROPERTIES eaxProperties;
|
||||
FMOD_RESULT result;
|
||||
int room;
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX5", "Setting reverb properties for instance: %d\n", prop->Instance));
|
||||
|
||||
/*
|
||||
Make sure all reverb effects are disabled on the mixer sources
|
||||
*/
|
||||
if (!mMixerReverbDisabled)
|
||||
{
|
||||
room = -10000;
|
||||
FMOD_memcpy(&sourceGUID, &FMOD_EAXPROPERTYID_EAX50_Source, sizeof(GUID));
|
||||
|
||||
// Only the first mixer source is technically used (multichannel source), but set all anyway
|
||||
for (int i = mMixerSourceOffset; i < mNumSources; i++)
|
||||
{
|
||||
mEAXSet(&sourceGUID, EAXSOURCE_ROOM, mSources[i].sid, &room, sizeof(int));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
return FMOD_ERR_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
mMixerReverbDisabled = true;
|
||||
}
|
||||
|
||||
/*
|
||||
Each reverb instance is equivalent to a hardware effect slot,
|
||||
attempt to lock that slot for use by FMOD
|
||||
*/
|
||||
switch (prop->Instance)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX50_FXSlot1, sizeof(GUID));
|
||||
if (!gEAX5LockedOALFxSlot1)
|
||||
{
|
||||
result = lockSlotEAX5(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX5LockedOALFxSlot1 = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX50_FXSlot2, sizeof(GUID));
|
||||
if (!gEAX5LockedOALFxSlot2)
|
||||
{
|
||||
result = lockSlotEAX5(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX5LockedOALFxSlot2 = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX50_FXSlot3, sizeof(GUID));
|
||||
if (!gEAX5LockedOALFxSlot3)
|
||||
{
|
||||
result = lockSlotEAX5(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX5LockedOALFxSlot3 = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FMOD_memcpy(&slotGUID, &FMOD_EAXPROPERTYID_EAX50_FXSlot0, sizeof(GUID));
|
||||
if (!gEAX5LockedOALFxSlot0)
|
||||
{
|
||||
result = lockSlotEAX5(slotGUID);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
gEAX5LockedOALFxSlot0 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FMOD_memset(&eaxProperties, 0, sizeof(EAXREVERBPROPERTIES));
|
||||
eaxProperties.ulEnvironment = prop->Environment < 0 ? 0 : prop->Environment;
|
||||
eaxProperties.flEnvironmentSize = prop->EnvSize;
|
||||
eaxProperties.flEnvironmentDiffusion = prop->EnvDiffusion;
|
||||
eaxProperties.lRoom = prop->Room;
|
||||
eaxProperties.lRoomHF = prop->RoomHF;
|
||||
eaxProperties.lRoomLF = prop->RoomLF;
|
||||
eaxProperties.flDecayTime = prop->DecayTime;
|
||||
eaxProperties.flDecayHFRatio = prop->DecayHFRatio;
|
||||
eaxProperties.flDecayLFRatio = prop->DecayLFRatio;
|
||||
eaxProperties.lReflections = prop->Reflections;
|
||||
eaxProperties.flReflectionsDelay = prop->ReflectionsDelay;
|
||||
eaxProperties.vReflectionsPan.x = prop->ReflectionsPan[0];
|
||||
eaxProperties.vReflectionsPan.y = prop->ReflectionsPan[1];
|
||||
eaxProperties.vReflectionsPan.z = prop->ReflectionsPan[2];
|
||||
eaxProperties.lReverb = prop->Reverb;
|
||||
eaxProperties.flReverbDelay = prop->ReverbDelay;
|
||||
eaxProperties.vReverbPan.x = prop->ReverbPan[0];
|
||||
eaxProperties.vReverbPan.y = prop->ReverbPan[1];
|
||||
eaxProperties.vReverbPan.z = prop->ReverbPan[2];
|
||||
eaxProperties.flEchoTime = prop->EchoTime;
|
||||
eaxProperties.flEchoDepth = prop->EchoDepth;
|
||||
eaxProperties.flModulationTime = prop->ModulationTime;
|
||||
eaxProperties.flModulationDepth = prop->ModulationDepth;
|
||||
eaxProperties.flAirAbsorptionHF = prop->AirAbsorptionHF;
|
||||
eaxProperties.flHFReference = prop->HFReference;
|
||||
eaxProperties.flLFReference = prop->LFReference;
|
||||
eaxProperties.flRoomRolloffFactor = prop->RoomRolloffFactor;
|
||||
eaxProperties.ulFlags = prop->Flags & 0xFF; // Mask out FMOD specific flags, leaving only EAX flags
|
||||
|
||||
mEAXSet(&slotGUID, EAXREVERB_ALLPARAMETERS, 0, &eaxProperties, sizeof(EAXREVERBPROPERTIES));
|
||||
if (mOALFnTable.alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "OutputOpenAL::setPropertiesEAX5", "Error setting reverb properties\n"));
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
} /* namespace FMOD */
|
||||
|
||||
#endif /* FMOD_SUPPORT_EAX */
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
329
fmod/win32/src/fmod_output_timer.cpp
Executable file
329
fmod/win32/src/fmod_output_timer.cpp
Executable file
|
|
@ -0,0 +1,329 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_SOFTWARE
|
||||
|
||||
#include "fmod_output_timer.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
|
||||
// #define DUMPMIXERTODISK
|
||||
|
||||
#ifdef DUMPMIXERTODISK
|
||||
|
||||
#include <stdio.h>
|
||||
static FILE *fp = 0;
|
||||
|
||||
#endif
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputTimer::timerFunc()
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
unsigned int playPosition = 0;
|
||||
unsigned int blockSize = 0;
|
||||
int numBlocks = 0;
|
||||
FMOD_SOUND_FORMAT outputFormat = FMOD_SOUND_FORMAT_NONE;
|
||||
int outputChannels = 0;
|
||||
|
||||
// Playing has stopped
|
||||
if (!mPlaying)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
// Attempt to apply a pro-audio thread characteristic to reduce stuttering
|
||||
if (!mThreadElevated)
|
||||
{
|
||||
HANDLE (WINAPI *SetThreadTask)(LPCTSTR, LPDWORD);
|
||||
FMOD_OS_LIBRARY *avrtHandle = NULL;
|
||||
DWORD taskIndex = 0;
|
||||
|
||||
result = FMOD_OS_Library_Load("avrt.dll", &avrtHandle);
|
||||
if (result == FMOD_OK) // If this fails, OS does not support setting thread characteristics
|
||||
{
|
||||
result = FMOD_OS_Library_GetProcAddress(avrtHandle, "AvSetMmThreadCharacteristicsA", (void **)&SetThreadTask);
|
||||
if (result == FMOD_OK)
|
||||
{
|
||||
SetThreadTask("Pro Audio", &taskIndex);
|
||||
FLOG((FMOD_DEBUG_LEVEL_LOG, __FILE__, __LINE__, "OutputTimer::timerFunc", "Mixer thread set to 'Pro Audio' characteristic\n"));
|
||||
FMOD_OS_Library_Free(avrtHandle);
|
||||
}
|
||||
}
|
||||
|
||||
mThreadElevated = true; // This will prevent reattempting to elevate if already elevated and if the OS doesn't support it
|
||||
}
|
||||
|
||||
mSystem->mDSPTimeStamp.stampIn();
|
||||
|
||||
result = mSystem->getDSPBufferSize(&blockSize, &numBlocks);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mSystem->getSoftwareFormat(0, &outputFormat, &outputChannels, 0, 0, 0);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mDescription.getposition)
|
||||
{
|
||||
result = mDescription.getposition(this, &playPosition);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine which block is currently playing
|
||||
playPosition /= blockSize;
|
||||
playPosition %= numBlocks;
|
||||
|
||||
FLOG((FMOD_DEBUG_TYPE_THREAD, __FILE__, __LINE__, "OutputTimer::timerFunc", "Play block %8d, Fill block %8d\n", playPosition, mFillBlock));
|
||||
|
||||
while (mFillBlock != (int)playPosition)
|
||||
{
|
||||
void *ptr1 = NULL;
|
||||
void *ptr2 = NULL;
|
||||
unsigned int len1 = 0;
|
||||
unsigned int len2 = 0;
|
||||
unsigned int writePositionBytes = 0;
|
||||
unsigned int blockSizeBytes = 0;
|
||||
unsigned int samplesLocked = 0;
|
||||
|
||||
result = SoundI::getBytesFromSamples(blockSize, &blockSizeBytes, outputChannels, outputFormat);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = SoundI::getBytesFromSamples(mFillBlock * blockSize, &writePositionBytes, outputChannels, outputFormat);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mDescription.lock)
|
||||
{
|
||||
result = mDescription.lock(this, writePositionBytes, blockSizeBytes, &ptr1, &ptr2, &len1, &len2);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = SoundI::getSamplesFromBytes(len1, &samplesLocked, outputChannels, outputFormat);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mix(ptr1, samplesLocked);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef DUMPMIXERTODISK
|
||||
if (fp)
|
||||
{
|
||||
fwrite(ptr1, len1, 1, fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
ptr2 and len2 should never be non 0. All updates are block aligned.
|
||||
*/
|
||||
if (mDescription.unlock)
|
||||
{
|
||||
result = mDescription.unlock(this, ptr1, ptr2, len1, len2);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
mFillBlock++;
|
||||
if (mFillBlock >= numBlocks)
|
||||
{
|
||||
mFillBlock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mSystem->mDSPTimeStamp.stampOut(95);
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputTimer::start()
|
||||
{
|
||||
FMOD_RESULT result = FMOD_OK;
|
||||
unsigned int blockSize = 0;
|
||||
int sampleRate = 0;
|
||||
|
||||
/*
|
||||
Calculate the callback time for the mixer
|
||||
*/
|
||||
result = mSystem->getDSPBufferSize(&blockSize, NULL);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mSystem->getSoftwareFormat(&sampleRate, NULL, NULL, NULL, NULL, NULL);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
mMixerTimerPeriod = (float)blockSize * 1000.0f / (float)sampleRate;
|
||||
if (mMixerTimerPeriod < 20)
|
||||
{
|
||||
mMixerTimerPeriod /= 3;
|
||||
if (mMixerTimerPeriod < 1)
|
||||
{
|
||||
mMixerTimerPeriod = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mMixerTimerPeriod = 10;
|
||||
}
|
||||
|
||||
FLOG((FMOD_DEBUG_TYPE_THREAD, __FILE__, __LINE__, "OutputTimer::start", "Starting timer callback that triggers every %d ms\n", (int)mMixerTimerPeriod));
|
||||
mPlaying = true;
|
||||
|
||||
// Mixer update callback critical section
|
||||
result = FMOD_OS_CriticalSection_Create(&mMixerCrit);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Setup the timed callback event
|
||||
mThreadElevated = false;
|
||||
mMixerTimerID = timeSetEvent((unsigned int)mMixerTimerPeriod, 0, (LPTIMECALLBACK)timerFuncCallback, (UINT_PTR)this, TIME_PERIODIC);
|
||||
if (!mMixerTimerID)
|
||||
{
|
||||
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "OutputTimer::start", "timeSetEvent failed! Something is really wrong with your PC. timer period = %d ms\n", (int)mMixerTimerPeriod));
|
||||
return FMOD_ERR_OUTPUT_INIT;
|
||||
}
|
||||
|
||||
#ifdef DUMPMIXERTODISK
|
||||
fp = fopen("/media/fmod4output.raw", "wb");
|
||||
#endif
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT OutputTimer::stop()
|
||||
{
|
||||
FMOD_RESULT fResult = FMOD_OK;
|
||||
HRESULT hResult = S_OK;
|
||||
|
||||
// Stop mixer callbacks
|
||||
timeKillEvent(mMixerTimerID);
|
||||
mMixerTimerID = 0;
|
||||
|
||||
// If timer still ticks a few times ensure the callback will do nothing
|
||||
mPlaying = false;
|
||||
|
||||
// Ensure that the mixer is finish before returning (wont re-enter because of mPlaying)
|
||||
FMOD_OS_CriticalSection_Enter(mMixerCrit);
|
||||
|
||||
#ifdef DUMPMIXERTODISK
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
FMOD_OS_CriticalSection_Leave(mMixerCrit);
|
||||
FMOD_OS_CriticalSection_Free(mMixerCrit);
|
||||
mMixerCrit = NULL;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
void CALLBACK OutputTimer::timerFuncCallback(UINT uTimerID, UINT uMsg, UINT_PTR dwUser, UINT_PTR dw1, UINT_PTR dw2)
|
||||
{
|
||||
OutputTimer *outputTimer = (OutputTimer *)dwUser;
|
||||
|
||||
FMOD_OS_CriticalSection_Enter(outputTimer->mMixerCrit);
|
||||
outputTimer->timerFunc();
|
||||
FMOD_OS_CriticalSection_Leave(outputTimer->mMixerCrit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
37
fmod/win32/src/fmod_output_timer.h
Executable file
37
fmod/win32/src/fmod_output_timer.h
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef _FMOD_OUTPUT_TIMER_H
|
||||
#define _FMOD_OUTPUT_TIMER_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#include "fmod_outputi.h"
|
||||
#include "fmod_codec_wav.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class OutputTimer : public Output
|
||||
{
|
||||
private:
|
||||
|
||||
float mMixerTimerPeriod;
|
||||
unsigned int mMixerTimerID;
|
||||
bool mPlaying;
|
||||
bool mThreadElevated;
|
||||
FMOD_OS_CRITICALSECTION *mMixerCrit;
|
||||
|
||||
FMOD_RESULT timerFunc();
|
||||
|
||||
static void CALLBACK timerFuncCallback(UINT uTimerID, UINT uMsg, UINT_PTR dwUser, UINT_PTR dw1, UINT_PTR dw2);
|
||||
|
||||
protected:
|
||||
|
||||
int mFillBlock;
|
||||
|
||||
public:
|
||||
|
||||
FMOD_RESULT start();
|
||||
FMOD_RESULT stop();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2646
fmod/win32/src/fmod_output_wasapi.cpp
Executable file
2646
fmod/win32/src/fmod_output_wasapi.cpp
Executable file
File diff suppressed because it is too large
Load diff
171
fmod/win32/src/fmod_output_wasapi.h
Executable file
171
fmod/win32/src/fmod_output_wasapi.h
Executable file
|
|
@ -0,0 +1,171 @@
|
|||
#ifndef _FMOD_OUTPUT_WASAPI_H
|
||||
#define _FMOD_OUTPUT_WASAPI_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WASAPI
|
||||
|
||||
#include "fmod_systemi.h"
|
||||
#include "fmod_outputi.h"
|
||||
#include "fmod_memorytracker.h"
|
||||
#include "fmod_stringw.h"
|
||||
|
||||
// 0x0600 is Vista (safe since WASAPI output mode is only available on Vista)
|
||||
#define _WIN32_WINNT 0x0601
|
||||
#include <Windows.h>
|
||||
|
||||
#include "wasapi\fmod_audioclient.h"
|
||||
#include "wasapi\fmod_mmdeviceapi.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
typedef struct FMOD_WASAPIDriver
|
||||
{
|
||||
LPWSTR id;
|
||||
short *name;
|
||||
} FMOD_WASAPIDriver;
|
||||
|
||||
typedef struct FMOD_WASAPIRecordMembers
|
||||
{
|
||||
bool mRecordStereoToMono;
|
||||
IAudioClient *mCaptureAudioClient;
|
||||
IAudioCaptureClient *mCaptureClient;
|
||||
UINT mCaptureBufferLength;
|
||||
BYTE *mRecordBuffer;
|
||||
int mRecordBlockAlign;
|
||||
int mRecordWritePosition;
|
||||
} FMOD_WASAPIRecordMembers;
|
||||
|
||||
class OutputWASAPI : public Output
|
||||
{
|
||||
DECLARE_MEMORYTRACKER_NONVIRTUAL
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
General variables
|
||||
*/
|
||||
bool mCoInitialized;
|
||||
bool mInitialised;
|
||||
bool mExclusiveMode;
|
||||
|
||||
/*
|
||||
Render variables
|
||||
*/
|
||||
int mNumRenderDrivers;
|
||||
FMOD_WASAPIDriver mRenderDrivers[FMOD_OUTPUT_MAXDRIVERS];
|
||||
IAudioClient *mRenderAudioClient;
|
||||
IAudioRenderClient *mRenderClient;
|
||||
UINT mRenderBufferLength;
|
||||
int mRenderBlockAlign;
|
||||
FMOD_SOUND_FORMAT mRenderFormat;
|
||||
int mRenderChannels;
|
||||
HANDLE mFeederEventHandle;
|
||||
bool mFeederThreadElevated;
|
||||
Thread mFeederThread;
|
||||
unsigned int mFeederTimeout;
|
||||
Thread mMixerThread;
|
||||
BYTE *mMixerBuffer;
|
||||
int mMixerBufferLength;
|
||||
UINT mMixerBufferBlockSize;
|
||||
int mMixerBufferNumBlocks;
|
||||
int mMixerReadPosition;
|
||||
int mMixerWritePosition;
|
||||
DSPResampler *mMixerResamplerDSP;
|
||||
float *mMixerFormatConversionBuffer;
|
||||
unsigned int mMixerFormatConversionBufferSizeBytes;
|
||||
float *mMixerChannelConversionBuffer;
|
||||
unsigned int mMixerChannelConversionBufferSizeBytes;
|
||||
|
||||
/*
|
||||
Capture variables
|
||||
*/
|
||||
int mNumCaptureDrivers;
|
||||
FMOD_WASAPIDriver mCaptureDrivers[FMOD_OUTPUT_MAXDRIVERS];
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
HANDLE mRecordEventHandle;
|
||||
bool mRecordThreadElevated;
|
||||
Thread mRecordThread;
|
||||
|
||||
bool mRecordInitialised;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Private methods
|
||||
*/
|
||||
FMOD_RESULT enumerateDefaultDevices (IMMDeviceEnumerator *pEnumerator);
|
||||
FMOD_RESULT enumerate ();
|
||||
FMOD_RESULT parseUUIDString (WCHAR *srcString, FMOD_GUID *destGUID);
|
||||
FMOD_RESULT feederUpdate ();
|
||||
FMOD_RESULT mixerUpdate ();
|
||||
FMOD_RESULT channelConvert (float *outbuffer, float *inbuffer, int outchannels, int inchannels, int length);
|
||||
FMOD_RESULT cleanUpEnumeration ();
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
FMOD_RESULT recordUpdate ();
|
||||
#endif
|
||||
|
||||
static void feederThreadCallback (void *userdata);
|
||||
static void mixerThreadCallback (void *userdata);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
static void recordThreadCallback (void *userdata);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
static FMOD_OUTPUT_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
FMOD_RESULT getNumDrivers (int *numdrivers);
|
||||
FMOD_RESULT getDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverInfoW (int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverCapsEx (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode);
|
||||
FMOD_RESULT initEx (int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, FMOD_SPEAKERMODE *speakermode, int dspbufferlength, int dspnumbuffers, int max2dchannels, int max3dchannels, void *extradriverdata);
|
||||
FMOD_RESULT close ();
|
||||
FMOD_RESULT getHandle (void **handle);
|
||||
FMOD_RESULT start ();
|
||||
FMOD_RESULT stop ();
|
||||
FMOD_RESULT mixerResampleRead (float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
FMOD_RESULT recordGetNumDrivers (int *numdrivers);
|
||||
FMOD_RESULT recordGetDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordGetDriverInfoW (int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordGetDriverCaps (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency);
|
||||
FMOD_RESULT recordStart (FMOD_RECORDING_INFO *recordinfo, Sound *sound, bool loop);
|
||||
FMOD_RESULT recordStop (FMOD_RECORDING_INFO *recordinfo);
|
||||
FMOD_RESULT recordGetPosition (FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
FMOD_RESULT recordLock (FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
#endif
|
||||
|
||||
static FMOD_RESULT F_CALLBACK getNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverCapsExCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode);
|
||||
static FMOD_RESULT F_CALLBACK initExCallback (FMOD_OUTPUT_STATE *output, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, FMOD_SPEAKERMODE *speakermode, int dspbufferlength, int dspnumbuffers, int max2dchannels, int max3dchannels, void *extradriverdata);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK startCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK stopCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getHandleCallback (FMOD_OUTPUT_STATE *output, void **handle);
|
||||
static FMOD_RESULT F_CALLBACK mixerResampleReadCallback (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
static FMOD_RESULT F_CALLBACK recordGetNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverCapsCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency);
|
||||
static FMOD_RESULT F_CALLBACK recordStartCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, FMOD_SOUND *sound, int loop);
|
||||
static FMOD_RESULT F_CALLBACK recordStopCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo);
|
||||
static FMOD_RESULT F_CALLBACK recordGetPositionCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK recordLockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
#endif
|
||||
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
static FMOD_RESULT F_CALLBACK getMemoryUsedCallback (FMOD_OUTPUT_STATE *output, MemoryTracker *tracker);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_WASAPI */
|
||||
|
||||
#endif /* _FMOD_OUTPUT_WASAPI_H */
|
||||
1726
fmod/win32/src/fmod_output_winmm.cpp
Executable file
1726
fmod/win32/src/fmod_output_winmm.cpp
Executable file
File diff suppressed because it is too large
Load diff
116
fmod/win32/src/fmod_output_winmm.h
Executable file
116
fmod/win32/src/fmod_output_winmm.h
Executable file
|
|
@ -0,0 +1,116 @@
|
|||
#ifndef _FMOD_OUTPUT_WINMM_H
|
||||
#define _FMOD_OUTPUT_WINMM_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WINMM
|
||||
|
||||
#include "fmod_output_polled.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
const int PLAY_MAXBLOCKS = 1; /* number of buffers */
|
||||
const int RECORD_MAXBLOCKS = 100; /* number of buffers */
|
||||
const int RECORD_BLOCKLENMS = 5; /* size of each buffer - 100 * 5 = 500ms with 5ms granularity */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WAVEHDR wavehdr;
|
||||
char *data;
|
||||
} SoundBlock;
|
||||
|
||||
class OutputWinMM : public OutputPolled
|
||||
{
|
||||
private:
|
||||
|
||||
bool mCoInitialized;
|
||||
|
||||
/*
|
||||
Playback information.
|
||||
*/
|
||||
HWAVEOUT mHandle;
|
||||
bool mRunning;
|
||||
char *mBuffer;
|
||||
SoundBlock mBlock[PLAY_MAXBLOCKS];
|
||||
int mNumBlocks;
|
||||
unsigned int mBlockLengthBytes;
|
||||
|
||||
/*
|
||||
Record information.
|
||||
*/
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
HWAVEIN mRecordHandle;
|
||||
Thread mRecordThread;
|
||||
bool mRecording;
|
||||
int mRecordCurrentBlock;
|
||||
int mRecordNextBlock;
|
||||
SoundBlock mRecordBlock[RECORD_MAXBLOCKS];
|
||||
char *mRecordData;
|
||||
unsigned int mRecordBlockLenBytes;
|
||||
int mRecordBlockAlign;
|
||||
|
||||
static void CALLBACK recordCallback(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
|
||||
static void recordThreadCallback(void *userdata);
|
||||
FMOD_RESULT recordThread();
|
||||
#endif
|
||||
|
||||
FMOD_RESULT testFormat(int id, FMOD_SOUND_FORMAT format, int channels);
|
||||
|
||||
public:
|
||||
|
||||
static FMOD_OUTPUT_DESCRIPTION_EX *getDescriptionEx();
|
||||
|
||||
FMOD_RESULT enumerate();
|
||||
FMOD_RESULT getNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT getDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverInfoW(int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT getDriverCaps(int id, FMOD_CAPS *caps);
|
||||
FMOD_RESULT init(int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbuffersize, int dspnumbuffers, void *extradriverdata);
|
||||
FMOD_RESULT close();
|
||||
FMOD_RESULT getHandle(void **handle);
|
||||
FMOD_RESULT start();
|
||||
FMOD_RESULT stop();
|
||||
FMOD_RESULT getPosition(unsigned int *pcm);
|
||||
FMOD_RESULT lock(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT unlock(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
FMOD_RESULT recordGetNumDrivers(int *numdrivers);
|
||||
FMOD_RESULT recordGetDriverInfo(int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordGetDriverInfoW(int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
FMOD_RESULT recordStart (FMOD_RECORDING_INFO *recordinfo, Sound *sound, bool loop);
|
||||
FMOD_RESULT recordStop (FMOD_RECORDING_INFO *recordinfo);
|
||||
FMOD_RESULT recordGetPosition (FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
FMOD_RESULT recordLock (FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
#endif
|
||||
|
||||
static FMOD_RESULT F_CALLBACK getNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK getDriverCapsCallback (FMOD_OUTPUT_STATE *output, int id, FMOD_CAPS *caps);
|
||||
static FMOD_RESULT F_CALLBACK initCallback (FMOD_OUTPUT_STATE *output, int selecteddriver, FMOD_INITFLAGS flags, int *outputrate, int outputchannels, FMOD_SOUND_FORMAT *outputformat, int dspbufferlength, int dspnumbuffers, void *extradriverdata);
|
||||
static FMOD_RESULT F_CALLBACK closeCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK startCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK stopCallback (FMOD_OUTPUT_STATE *output);
|
||||
static FMOD_RESULT F_CALLBACK getHandleCallback (FMOD_OUTPUT_STATE *output, void **handle);
|
||||
static FMOD_RESULT F_CALLBACK getPositionCallback (FMOD_OUTPUT_STATE *output, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK lockCallback (FMOD_OUTPUT_STATE *output, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
static FMOD_RESULT F_CALLBACK unlockCallback (FMOD_OUTPUT_STATE *output, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
#ifdef FMOD_SUPPORT_RECORDING
|
||||
static FMOD_RESULT F_CALLBACK recordGetNumDriversCallback (FMOD_OUTPUT_STATE *output, int *numdrivers);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoCallback (FMOD_OUTPUT_STATE *output, int id, char *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordGetDriverInfoWCallback (FMOD_OUTPUT_STATE *output, int id, short *name, int namelen, FMOD_GUID *guid);
|
||||
static FMOD_RESULT F_CALLBACK recordStartCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, FMOD_SOUND *sound, int loop);
|
||||
static FMOD_RESULT F_CALLBACK recordStopCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo);
|
||||
static FMOD_RESULT F_CALLBACK recordGetPositionCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int *pcm);
|
||||
static FMOD_RESULT F_CALLBACK recordLockCallback (FMOD_OUTPUT_STATE *output, FMOD_RECORDING_INFO *recordinfo, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* #ifdef FMOD_SUPPORT_WINMM */
|
||||
|
||||
#endif
|
||||
256
fmod/win32/src/fmod_sample_dsound.cpp
Executable file
256
fmod/win32/src/fmod_sample_dsound.cpp
Executable file
|
|
@ -0,0 +1,256 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_DSOUND
|
||||
|
||||
#include "fmod.h"
|
||||
#include "fmod_output_dsound.h"
|
||||
#include "fmod_sample_dsound.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
SampleDSound::SampleDSound()
|
||||
{
|
||||
mBuffer = 0;
|
||||
mBuffer3D = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleDSound::release(bool freethis)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
if (!mSystem)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (mFlags & FMOD_SOUND_FLAG_PRELOADEDFSB)
|
||||
{
|
||||
return FMOD_ERR_PRELOADED;
|
||||
}
|
||||
|
||||
if (mFlags & FMOD_SOUND_FLAG_PROGRAMMERSOUND)
|
||||
{
|
||||
return FMOD_ERR_PROGRAMMERSOUND;
|
||||
}
|
||||
|
||||
while (mOpenState != FMOD_OPENSTATE_READY && mOpenState != FMOD_OPENSTATE_ERROR)
|
||||
{
|
||||
FMOD_OS_Time_Sleep(2);
|
||||
}
|
||||
|
||||
result = mSystem->stopSound(this);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Free sample's secondary buffer
|
||||
*/
|
||||
if (mBuffer)
|
||||
{
|
||||
if (mOutput)
|
||||
{
|
||||
mOutput->mBufferMemoryCurrent -= mLengthBytes;
|
||||
}
|
||||
|
||||
mBuffer->Release();
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
if(mBuffer3D)
|
||||
{
|
||||
mBuffer3D->Release();
|
||||
mBuffer3D = 0;
|
||||
}
|
||||
|
||||
return Sample::release(freethis);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleDSound::lockInternal(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!mBuffer)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
hr = mBuffer->Lock(offset, length, ptr1, (DWORD *)len1, ptr2, (DWORD *)len2, 0); /* not DSBLOCK_FROMWRITECURSOR OR DSBLOCK_ENTIREBUFFER */
|
||||
if (hr == E_INVALIDARG)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
else if (hr == DSBSTATUS_BUFFERLOST)
|
||||
{
|
||||
DWORD locflags = 0;
|
||||
|
||||
if (!(mMode & FMOD_UNIQUE))
|
||||
{
|
||||
if (mLOCSoftware)
|
||||
{
|
||||
locflags |= DSBPLAY_LOCSOFTWARE;
|
||||
}
|
||||
else
|
||||
{
|
||||
locflags |= DSBPLAY_LOCHARDWARE;
|
||||
}
|
||||
}
|
||||
mBuffer->Restore();
|
||||
mBuffer->Play(0, 0, locflags | DSBPLAY_LOOPING);
|
||||
}
|
||||
else if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
|
||||
}
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
FMOD_OK
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
Win32, Win64
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleDSound::unlockInternal(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!mBuffer)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (mFormat == FMOD_SOUND_FORMAT_PCM8)
|
||||
{
|
||||
if (ptr1 && len1)
|
||||
{
|
||||
unsigned int count;
|
||||
unsigned char *destptr = (unsigned char *)ptr1;
|
||||
|
||||
for (count = 0; count < len1; count++)
|
||||
{
|
||||
*destptr++ ^= 128;
|
||||
}
|
||||
}
|
||||
if (ptr2 && len2)
|
||||
{
|
||||
unsigned int count;
|
||||
unsigned char *destptr = (unsigned char *)ptr2;
|
||||
|
||||
for (count = 0; count < len2; count++)
|
||||
{
|
||||
*destptr++ ^= 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr = mBuffer->Unlock(ptr1, len1, ptr2, len2);
|
||||
if (hr != DS_OK)
|
||||
{
|
||||
return FMOD_ERR_OUTPUT_DRIVERCALL;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
|
||||
#ifdef FMOD_SUPPORT_MEMORYTRACKER
|
||||
|
||||
FMOD_RESULT SampleDSound::getMemoryUsedImpl(MemoryTracker *tracker)
|
||||
{
|
||||
tracker->add(false, FMOD_MEMBITS_SOUND, sizeof(SampleDSound) - sizeof(Sample)); // only the SampleDSound members...
|
||||
|
||||
return Sample::getMemoryUsedImpl(tracker); // all the base class members
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_DSOUND */
|
||||
52
fmod/win32/src/fmod_sample_dsound.h
Executable file
52
fmod/win32/src/fmod_sample_dsound.h
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef _FMOD_SAMPLE_DSOUND_H
|
||||
#define _FMOD_SAMPLE_DSOUND_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_DSOUND
|
||||
|
||||
#include "fmod_memory.h"
|
||||
#include "fmod_soundi.h"
|
||||
#include "fmod_sound_sample.h"
|
||||
|
||||
#ifndef _FMOD_MEMORYTRACKER_H
|
||||
#include "fmod_memorytracker.h"
|
||||
#endif
|
||||
|
||||
struct IDirectSoundBuffer8;
|
||||
struct IDirectSound3DBuffer;
|
||||
struct OutputDSound;
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class SampleDSound : public Sample
|
||||
{
|
||||
DECLARE_MEMORYTRACKER
|
||||
|
||||
friend class ChannelDSound;
|
||||
friend class OutputDSound;
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
friend class OutputOpenAL;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
IDirectSoundBuffer8 *mBuffer;
|
||||
IDirectSound3DBuffer *mBuffer3D;
|
||||
OutputDSound *mOutput;
|
||||
bool mLOCSoftware;
|
||||
|
||||
public:
|
||||
|
||||
SampleDSound();
|
||||
|
||||
FMOD_RESULT release(bool freethis = true);
|
||||
FMOD_RESULT lockInternal(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT unlockInternal(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_DSOUND */
|
||||
|
||||
#endif
|
||||
503
fmod/win32/src/fmod_sample_openal.cpp
Executable file
503
fmod/win32/src/fmod_sample_openal.cpp
Executable file
|
|
@ -0,0 +1,503 @@
|
|||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
|
||||
#include "fmod_memory.h"
|
||||
#include "fmod_output.h"
|
||||
#include "fmod_output_software.h"
|
||||
#include "fmod_sample_openal.h"
|
||||
#include "fmod_systemi.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
SampleOpenAL::SampleOpenAL()
|
||||
{
|
||||
mBuffer = 0;
|
||||
mBufferMemory = 0;
|
||||
mDataEndCopied = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::release(bool freethis)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
if (!mSystem)
|
||||
{
|
||||
return FMOD_ERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (mFlags & FMOD_SOUND_FLAG_PRELOADEDFSB)
|
||||
{
|
||||
return FMOD_ERR_PRELOADED;
|
||||
}
|
||||
|
||||
if (mFlags & FMOD_SOUND_FLAG_PROGRAMMERSOUND)
|
||||
{
|
||||
return FMOD_ERR_PROGRAMMERSOUND;
|
||||
}
|
||||
|
||||
while (mOpenState != FMOD_OPENSTATE_READY && mOpenState != FMOD_OPENSTATE_ERROR)
|
||||
{
|
||||
FMOD_OS_Time_Sleep(2);
|
||||
}
|
||||
|
||||
result = mSystem->stopSound(this);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mBufferMemory)
|
||||
{
|
||||
FMOD_Memory_Free(mBufferMemory);
|
||||
mBufferMemory = 0;
|
||||
}
|
||||
|
||||
if (mLoopPointDataEnd && mLoopPointDataEnd != mLoopPointDataEndMemory)
|
||||
{
|
||||
FMOD_Memory_Free(mLoopPointDataEnd);
|
||||
mLoopPointDataEnd = 0;
|
||||
}
|
||||
|
||||
mBuffer = 0;
|
||||
|
||||
return Sample::release(freethis);
|
||||
}
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::setMode(FMOD_MODE mode)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = Sample::setMode(mode);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = setLoopPointData();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::lockInternal(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
char *src = 0;
|
||||
unsigned int overflowbytes, pointB;
|
||||
|
||||
/*
|
||||
If we're locking part of the sample that has been modified by the loop point stuff, restore the old data first.
|
||||
*/
|
||||
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (offset >= pointB && offset < pointB + overflowbytes)
|
||||
{
|
||||
result = restoreLoopPointData();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
src = (char *)mBuffer;
|
||||
|
||||
if (offset >= mLengthBytes || offset < 0 || length < 0)
|
||||
{
|
||||
*ptr1 = 0;
|
||||
if (ptr2)
|
||||
{
|
||||
*ptr2 = 0;
|
||||
}
|
||||
*len1 = 0;
|
||||
if (len2)
|
||||
{
|
||||
*len2 = 0;
|
||||
}
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (offset + length <= mLengthBytes)
|
||||
{
|
||||
*ptr1 = src + offset;
|
||||
*len1 = length;
|
||||
if (ptr2)
|
||||
{
|
||||
*ptr2 = 0;
|
||||
}
|
||||
if (len2)
|
||||
{
|
||||
*len2 = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Otherwise return wrapped pointers in pt1 and ptr2
|
||||
*/
|
||||
else
|
||||
{
|
||||
*ptr1 = src + offset;
|
||||
*len1 = mLengthBytes - offset;
|
||||
*ptr2 = src;
|
||||
*len2 = length - (mLengthBytes - offset);
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::unlockInternal(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2)
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
|
||||
result = setLoopPointData();
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::setBufferData(void *data)
|
||||
{
|
||||
mBuffer = data;
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::setLoopPoints(unsigned int loopstart, unsigned int looplength)
|
||||
{
|
||||
if (loopstart >= mLength || loopstart + looplength > mLength)
|
||||
{
|
||||
return FMOD_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
restoreLoopPointData();
|
||||
|
||||
mLoopStart = loopstart;
|
||||
mLoopLength = looplength;
|
||||
|
||||
setLoopPointData();
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::setLoopPointData()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
unsigned int overflowbytes, pointA, pointB;
|
||||
|
||||
if ((mFormat != FMOD_SOUND_FORMAT_PCM8 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM16 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM24 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM32 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCMFLOAT) || !mLoopPointDataEnd)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = getBytesFromSamples(mLoopStart, &pointA);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (mMode & FMOD_LOOP_BIDI)
|
||||
{
|
||||
int count;
|
||||
|
||||
FMOD_memcpy(mLoopPointDataEnd, (char *)mBuffer + pointB, overflowbytes); /* backup the data first */
|
||||
mDataEndCopied = true;
|
||||
|
||||
switch (mFormat)
|
||||
{
|
||||
case FMOD_SOUND_FORMAT_PCM8:
|
||||
{
|
||||
char *srcptr, *destptr;
|
||||
|
||||
srcptr = destptr = (char *)mBuffer + pointB;
|
||||
srcptr -= mChannels;
|
||||
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
|
||||
{
|
||||
*destptr = *srcptr;
|
||||
destptr++;
|
||||
srcptr--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FMOD_SOUND_FORMAT_PCM16:
|
||||
{
|
||||
short *srcptr, *destptr;
|
||||
|
||||
srcptr = destptr = (short *)((char *)mBuffer + pointB);
|
||||
srcptr -= mChannels;
|
||||
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
|
||||
{
|
||||
*destptr = *srcptr;
|
||||
destptr++;
|
||||
srcptr--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FMOD_SOUND_FORMAT_PCM24:
|
||||
{
|
||||
char *srcptr, *destptr;
|
||||
|
||||
srcptr = destptr = (char *)mBuffer + pointB;
|
||||
srcptr -= (mChannels * 3);
|
||||
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
|
||||
{
|
||||
destptr[0] = srcptr[0];
|
||||
destptr[1] = srcptr[1];
|
||||
destptr[2] = srcptr[2];
|
||||
destptr += 3;
|
||||
srcptr -= 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FMOD_SOUND_FORMAT_PCM32:
|
||||
case FMOD_SOUND_FORMAT_PCMFLOAT:
|
||||
{
|
||||
int *srcptr, *destptr;
|
||||
|
||||
srcptr = destptr = (int *)((char *)mBuffer + pointB);
|
||||
srcptr -= mChannels;
|
||||
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
|
||||
{
|
||||
*destptr = *srcptr;
|
||||
destptr++;
|
||||
srcptr--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mMode & FMOD_LOOP_NORMAL)
|
||||
{
|
||||
FMOD_memcpy(mLoopPointDataEnd, (char *)mBuffer + pointB, overflowbytes);
|
||||
mDataEndCopied = true;
|
||||
|
||||
FMOD_memcpy((char *)mBuffer + pointB, (char *)mBuffer + pointA, overflowbytes);
|
||||
}
|
||||
else if (mMode & FMOD_LOOP_OFF)
|
||||
{
|
||||
if(mDataEndCopied)
|
||||
{
|
||||
FMOD_memcpy((char *)mBuffer + pointB, mLoopPointDataEnd,overflowbytes);
|
||||
}
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[
|
||||
[DESCRIPTION]
|
||||
|
||||
[PARAMETERS]
|
||||
|
||||
[RETURN_VALUE]
|
||||
|
||||
[REMARKS]
|
||||
|
||||
[PLATFORMS]
|
||||
|
||||
[SEE_ALSO]
|
||||
]
|
||||
*/
|
||||
FMOD_RESULT SampleOpenAL::restoreLoopPointData()
|
||||
{
|
||||
FMOD_RESULT result;
|
||||
unsigned int overflowbytes, pointA, pointB;
|
||||
|
||||
if ((mFormat != FMOD_SOUND_FORMAT_PCM8 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM16 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM24 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCM32 &&
|
||||
mFormat != FMOD_SOUND_FORMAT_PCMFLOAT) || !mLoopPointDataEnd)
|
||||
{
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = getBytesFromSamples(mLoopStart, &pointA);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if(mDataEndCopied)
|
||||
{
|
||||
FMOD_memcpy((char *)mBuffer + pointB, mLoopPointDataEnd,overflowbytes);
|
||||
}
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
45
fmod/win32/src/fmod_sample_openal.h
Executable file
45
fmod/win32/src/fmod_sample_openal.h
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _FMOD_SAMPLE_OPENAL_H
|
||||
#define _FMOD_SAMPLE_OPENAL_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_OPENAL
|
||||
|
||||
#include "fmod_dsp_resampler.h"
|
||||
#include "fmod_sound_sample.h"
|
||||
|
||||
namespace FMOD
|
||||
{
|
||||
class SampleOpenAL : public Sample
|
||||
{
|
||||
friend class OutputOpenAL;
|
||||
friend class ChannelOpenAL;
|
||||
friend class DSPWaveTable;
|
||||
|
||||
private:
|
||||
|
||||
void *mBuffer;
|
||||
void *mBufferMemory;
|
||||
char *mLoopPointDataEnd;
|
||||
char mLoopPointDataEndMemory[8];
|
||||
bool mDataEndCopied;
|
||||
|
||||
public:
|
||||
|
||||
SampleOpenAL();
|
||||
|
||||
FMOD_RESULT release(bool freethis = true);
|
||||
FMOD_RESULT lockInternal(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2);
|
||||
FMOD_RESULT unlockInternal(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2);
|
||||
FMOD_RESULT setBufferData(void *data);
|
||||
|
||||
FMOD_RESULT setLoopPoints(unsigned int loopstart, unsigned int looplength);
|
||||
FMOD_RESULT setLoopPointData();
|
||||
FMOD_RESULT restoreLoopPointData();
|
||||
FMOD_RESULT setMode(FMOD_MODE mode);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* FMOD_SUPPORT_OPENAL */
|
||||
|
||||
#endif
|
||||
15
fmod/win32/src/resource.h
Executable file
15
fmod/win32/src/resource.h
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by fmod.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
109
fmod/win32/src/wasapi/fmod_audioclient.h
Executable file
109
fmod/win32/src/wasapi/fmod_audioclient.h
Executable file
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef _FMOD_AUDIOCLIENT_H
|
||||
#define _FMOD_AUDIOCLIENT_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WASAPI
|
||||
|
||||
#include "fmod_codec_wav.h"
|
||||
|
||||
// GUIDs
|
||||
static const GUID IID_IAudioClock = { 0xcd63314f, 0x3fba, 0x4a1b, { 0x81, 0x2c, 0xef, 0x96, 0x35, 0x87, 0x28, 0xe7 } };
|
||||
static const GUID IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
static const GUID IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483, { 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
|
||||
static const GUID IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0, { 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
|
||||
static const GUID KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
|
||||
// Helper defines
|
||||
typedef LONGLONG REFERENCE_TIME;
|
||||
typedef const FMOD_GUID* LPCFMOD_GUID;
|
||||
typedef enum
|
||||
{
|
||||
AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_SHAREMODE_EXCLUSIVE
|
||||
} AUDCLNT_SHAREMODE;
|
||||
|
||||
// Error defines
|
||||
#define FACILITY_AUDCLNT 0x889
|
||||
#define AUDCLNT_ERR(n) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_AUDCLNT, n)
|
||||
#define AUDCLNT_SUCCESS(n) MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_AUDCLNT, n)
|
||||
#define AUDCLNT_E_NOT_INITIALIZED AUDCLNT_ERR(0x001)
|
||||
#define AUDCLNT_E_ALREADY_INITIALIZED AUDCLNT_ERR(0x002)
|
||||
#define AUDCLNT_E_WRONG_ENDPOINT_TYPE AUDCLNT_ERR(0x003)
|
||||
#define AUDCLNT_E_DEVICE_INVALIDATED AUDCLNT_ERR(0x004)
|
||||
#define AUDCLNT_E_NOT_STOPPED AUDCLNT_ERR(0x005)
|
||||
#define AUDCLNT_E_BUFFER_TOO_LARGE AUDCLNT_ERR(0x006)
|
||||
#define AUDCLNT_E_OUT_OF_ORDER AUDCLNT_ERR(0x007)
|
||||
#define AUDCLNT_E_UNSUPPORTED_FORMAT AUDCLNT_ERR(0x008)
|
||||
#define AUDCLNT_E_INVALID_SIZE AUDCLNT_ERR(0x009)
|
||||
#define AUDCLNT_E_DEVICE_IN_USE AUDCLNT_ERR(0x00a)
|
||||
#define AUDCLNT_E_BUFFER_OPERATION_PENDING AUDCLNT_ERR(0x00b)
|
||||
#define AUDCLNT_E_THREAD_NOT_REGISTERED AUDCLNT_ERR(0x00c)
|
||||
#define AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED AUDCLNT_ERR(0x00e)
|
||||
#define AUDCLNT_E_ENDPOINT_CREATE_FAILED AUDCLNT_ERR(0x00f)
|
||||
#define AUDCLNT_E_SERVICE_NOT_RUNNING AUDCLNT_ERR(0x010)
|
||||
#define AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED AUDCLNT_ERR(0x011)
|
||||
#define AUDCLNT_E_EXCLUSIVE_MODE_ONLY AUDCLNT_ERR(0x012)
|
||||
#define AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL AUDCLNT_ERR(0x013)
|
||||
#define AUDCLNT_E_EVENTHANDLE_NOT_SET AUDCLNT_ERR(0x014)
|
||||
#define AUDCLNT_E_INCORRECT_BUFFER_SIZE AUDCLNT_ERR(0x015)
|
||||
#define AUDCLNT_E_BUFFER_SIZE_ERROR AUDCLNT_ERR(0x016)
|
||||
#define AUDCLNT_E_CPUUSAGE_EXCEEDED AUDCLNT_ERR(0x017)
|
||||
#define AUDCLNT_S_BUFFER_EMPTY AUDCLNT_SUCCESS(0x001)
|
||||
#define AUDCLNT_S_THREAD_ALREADY_REGISTERED AUDCLNT_SUCCESS(0x002)
|
||||
#define AUDCLNT_S_POSITION_STALLED AUDCLNT_SUCCESS(0x003)
|
||||
|
||||
// AudioClient stream flags
|
||||
#define AUDCLNT_STREAMFLAGS_CROSSPROCESS 0x00010000
|
||||
#define AUDCLNT_STREAMFLAGS_LOOPBACK 0x00020000
|
||||
#define AUDCLNT_STREAMFLAGS_EVENTCALLBACK 0x00040000
|
||||
#define AUDCLNT_STREAMFLAGS_NOPERSIST 0x00080000
|
||||
|
||||
// Used to create and initialize a connection to the audio engine
|
||||
struct IAudioClient : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL Initialize (AUDCLNT_SHAREMODE ShareMode, DWORD StreamFlags, REFERENCE_TIME hnsBufferDuration, REFERENCE_TIME hnsPeriodicity, const FMOD::WAVE_FORMATEX *pFormat, LPCFMOD_GUID AudioSessionGuid) = 0;
|
||||
virtual HRESULT F_STDCALL GetBufferSize (UINT32 *pNumBufferFrames) = 0;
|
||||
virtual HRESULT F_STDCALL GetStreamLatency (REFERENCE_TIME *phnsLatency) = 0;
|
||||
virtual HRESULT F_STDCALL GetCurrentPadding (UINT32 *pNumPaddingFrames) = 0;
|
||||
virtual HRESULT F_STDCALL IsFormatSupported (AUDCLNT_SHAREMODE ShareMode, const FMOD::WAVE_FORMATEX *pFormat, FMOD::WAVE_FORMATEX **ppClosestMatch) = 0;
|
||||
virtual HRESULT F_STDCALL GetMixFormat (FMOD::WAVE_FORMATEX **ppDeviceFormat) = 0;
|
||||
virtual HRESULT F_STDCALL GetDevicePeriod (REFERENCE_TIME *phnsDefaultDevicePeriod, REFERENCE_TIME *phnsMinimumDevicePeriod) = 0;
|
||||
virtual HRESULT F_STDCALL Start (void) = 0;
|
||||
virtual HRESULT F_STDCALL Stop (void) = 0;
|
||||
virtual HRESULT F_STDCALL Reset (void) = 0;
|
||||
virtual HRESULT F_STDCALL SetEventHandle (HANDLE eventHandle) = 0;
|
||||
virtual HRESULT F_STDCALL GetService (REFIID riid, void **ppv) = 0;
|
||||
};
|
||||
|
||||
// Used for monitoring the stream data rate and stream position
|
||||
struct IAudioClock : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFrequency (UINT64 *pu64Frequency) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE GetPosition (UINT64 *pu64Position, UINT64 *pu64QPCPosition) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE GetCharacteristics (DWORD *pdwCharacteristics) = 0;
|
||||
};
|
||||
|
||||
// Used by audio-rendering applications to stream their output data to a rendering endpoint device
|
||||
struct IAudioRenderClient : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL GetBuffer (UINT32 NumFramesRequested, BYTE **ppData) = 0;
|
||||
virtual HRESULT F_STDCALL ReleaseBuffer (UINT32 NumFramesWritten, DWORD dwFlags) = 0;
|
||||
};
|
||||
|
||||
// Used by a capture application to read capture data from a capture endpoint buffer
|
||||
struct IAudioCaptureClient : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL GetBuffer (BYTE **ppData, UINT32 *pNumFramesToRead, DWORD *pdwFlags, UINT64 *pu64DevicePosition, UINT64 *pu64QPCPosition) = 0;
|
||||
virtual HRESULT F_STDCALL ReleaseBuffer (UINT32 NumFramesRead) = 0;
|
||||
virtual HRESULT F_STDCALL GetNextPacketSize (UINT32 *pNumFramesInNextPacket) = 0;
|
||||
};
|
||||
|
||||
#endif /* FMOD_SUPPORT_WASAPI */
|
||||
|
||||
#endif /* _FMOD_AUDIOCLIENT_H */
|
||||
125
fmod/win32/src/wasapi/fmod_mmdeviceapi.h
Executable file
125
fmod/win32/src/wasapi/fmod_mmdeviceapi.h
Executable file
|
|
@ -0,0 +1,125 @@
|
|||
#ifndef _FMOD_MMDEVICEAPI_H
|
||||
#define _FMOD_MMDEVICEAPI_H
|
||||
|
||||
#include "fmod_settings.h"
|
||||
|
||||
#ifdef FMOD_SUPPORT_WASAPI
|
||||
|
||||
// Audio data flow direction
|
||||
typedef enum
|
||||
{
|
||||
eRender,
|
||||
eCapture,
|
||||
eAll,
|
||||
EDataFlow_enum_count
|
||||
} EDataFlow;
|
||||
|
||||
// Role assigned to an audio endpoint
|
||||
typedef enum
|
||||
{
|
||||
eConsole,
|
||||
eMultimedia,
|
||||
eCommunications,
|
||||
ERole_enum_count
|
||||
} ERole;
|
||||
|
||||
// Identifier for a property
|
||||
#ifndef PROPERTYKEY_DEFINED
|
||||
#define PROPERTYKEY_DEFINED
|
||||
typedef struct
|
||||
{
|
||||
FMOD_GUID category;
|
||||
DWORD propertyID;
|
||||
} PROPERTYKEY;
|
||||
#endif
|
||||
|
||||
// GUIDs
|
||||
static const GUID CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c, { 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e }};
|
||||
static const GUID IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35, { 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6 }};
|
||||
static const GUID IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089, { 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 }};
|
||||
|
||||
// Property keys
|
||||
static const PROPERTYKEY PKEY_Device_DeviceDesc = { { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } }, 2 };
|
||||
static const PROPERTYKEY PKEY_DeviceInterface_FriendlyName = { { 0x026e516e, 0xb814, 0x414b, { 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22 } }, 2 };
|
||||
|
||||
// Helper defines
|
||||
#define REFPROPERTYKEY const PROPERTYKEY &
|
||||
#define REFPROPVARIANT const PROPVARIANT &
|
||||
|
||||
// Error defines
|
||||
#define E_NOTFOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND)
|
||||
#define E_UNSUPPORTED_TYPE HRESULT_FROM_WIN32(ERROR_UNSUPPORTED_TYPE)
|
||||
|
||||
// Device states
|
||||
#define DEVICE_STATE_ACTIVE 0x00000001
|
||||
#define DEVICE_STATE_DISABLED 0x00000002
|
||||
#define DEVICE_STATE_NOTPRESENT 0x00000004
|
||||
#define DEVICE_STATE_UNPLUGGED 0x00000008
|
||||
#define DEVICE_STATEMASK_ALL 0x0000000f
|
||||
|
||||
|
||||
// Property variant management
|
||||
#define PropVariantInit(pvar) FMOD_memset((pvar), 0, sizeof(PROPVARIANT))
|
||||
WINOLEAPI PropVariantClear ( PROPVARIANT * pvar );
|
||||
|
||||
// Provides methods for enumerating, getting, and setting property values
|
||||
struct IPropertyStore : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL GetCount (DWORD *cProps) = 0;
|
||||
virtual HRESULT F_STDCALL GetAt (DWORD iProp, PROPERTYKEY *pkey) = 0;
|
||||
virtual HRESULT F_STDCALL GetValue (REFPROPERTYKEY key, PROPVARIANT *pv) = 0;
|
||||
virtual HRESULT F_STDCALL SetValue (REFPROPERTYKEY key, REFPROPVARIANT propvar) = 0;
|
||||
virtual HRESULT F_STDCALL Commit (void) = 0;
|
||||
};
|
||||
|
||||
// Provices notification when an endpoint state has changed
|
||||
struct IMMNotificationClient : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL OnDeviceStateChanged (LPCWSTR pwstrDeviceId, DWORD dwNewState) = 0;
|
||||
virtual HRESULT F_STDCALL OnDeviceAdded (LPCWSTR pwstrDeviceId) = 0;
|
||||
virtual HRESULT F_STDCALL OnDeviceRemoved (LPCWSTR pwstrDeviceId) = 0;
|
||||
virtual HRESULT F_STDCALL OnDefaultDeviceChanged (EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) = 0;
|
||||
virtual HRESULT F_STDCALL OnPropertyValueChanged (LPCWSTR pwstrDeviceId, const PROPERTYKEY key) = 0;
|
||||
};
|
||||
|
||||
// Encapsulate the generic features of a multimedia device resource
|
||||
struct IMMDevice : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL Activate (REFIID iid, DWORD dwClsCtx, PROPVARIANT *pActivationParams, void **ppInterface) = 0;
|
||||
virtual HRESULT F_STDCALL OpenPropertyStore (DWORD stgmAccess, IPropertyStore **ppProperties) = 0;
|
||||
virtual HRESULT F_STDCALL GetId (LPWSTR *ppstrId) = 0;
|
||||
virtual HRESULT F_STDCALL GetState (DWORD *pdwState) = 0;
|
||||
};
|
||||
|
||||
// An audio endpoint device
|
||||
struct IMMEndpoint : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL GetDataFlow (EDataFlow *pDataFlow) = 0;
|
||||
};
|
||||
|
||||
// A collection of multimedia device resources
|
||||
struct IMMDeviceCollection : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL GetCount (UINT *pcDevices) = 0;
|
||||
virtual HRESULT F_STDCALL Item (UINT nDevice, IMMDevice **ppDevice) = 0;
|
||||
};
|
||||
|
||||
// Provides methods for enumerating multimedia device resources
|
||||
struct IMMDeviceEnumerator : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT F_STDCALL EnumAudioEndpoints (EDataFlow dataFlow, DWORD dwStateMask, IMMDeviceCollection **ppDevices) = 0;
|
||||
virtual HRESULT F_STDCALL GetDefaultAudioEndpoint (EDataFlow dataFlow, ERole role, IMMDevice **ppEndpoint) = 0;
|
||||
virtual HRESULT F_STDCALL GetDevice (LPCWSTR pwstrId, IMMDevice **ppDevice) = 0;
|
||||
virtual HRESULT F_STDCALL RegisterEndpointNotificationCallback (IMMNotificationClient *pClient) = 0;
|
||||
virtual HRESULT F_STDCALL UnregisterEndpointNotificationCallback (IMMNotificationClient *pClient) = 0;
|
||||
};
|
||||
|
||||
#endif /* FMOD_SUPPORT_WASAPI */
|
||||
|
||||
#endif /* _FMOD_MMDEVICEAPI_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue