Initial commit: ROW Client source code
Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AppStream.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CAppStream class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
#include <mediaobj.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "uuids.h"
|
||||
#include "dmo.h"
|
||||
#include "wave.h"
|
||||
#include "appstream.h"
|
||||
#include "dxutil.h" //to use free memory macro
|
||||
|
||||
//
|
||||
// CAppStream - reads data from a WAV file, transforms it using a DMO and then
|
||||
// copies the results into an output buffer.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::CAppStream()
|
||||
// Desc: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppStream::CAppStream():
|
||||
m_pObject(NULL),
|
||||
m_pObjectInPlace(NULL),
|
||||
m_pbInData(NULL),
|
||||
m_pwfx(NULL),
|
||||
m_uDataSize(0)
|
||||
{
|
||||
ZeroMemory(&m_mt, sizeof(m_mt));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::~CAppStream()
|
||||
// Desc: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CAppStream::~CAppStream()
|
||||
{
|
||||
|
||||
SAFE_RELEASE( m_pObject);
|
||||
SAFE_RELEASE( m_pObjectInPlace);
|
||||
SafeGlobalFree(m_pbInData);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::StreamData()
|
||||
// Desc: Load data from input file, create media object and set input&output type
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HRESULT CAppStream::StreamData( LPTSTR lpszInputFile,
|
||||
REFGUID rclsid,
|
||||
HWND hDlg,
|
||||
BYTE **ppbOutData,
|
||||
ULONG *pbDataSize,
|
||||
LPWAVEFORMATEX *ppwfx )
|
||||
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = Init( lpszInputFile, rclsid, hDlg );
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = Stream( ppbOutData, pbDataSize, ppwfx );
|
||||
if ( FAILED( hr )) {
|
||||
MessageBox( hDlg, TEXT("Streaming data failed."), TEXT(DEMO_NAME),
|
||||
MB_OK | MB_ICONERROR );
|
||||
return hr;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::Init()
|
||||
// Desc: Load data from input file, create media object and set input&output type
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HRESULT CAppStream::Init(LPTSTR lpszInputFile, REFGUID rclsid, HWND hDlg)
|
||||
{
|
||||
|
||||
// create DMO
|
||||
HRESULT hr = CoCreateInstance(rclsid,
|
||||
NULL,
|
||||
CLSCTX_INPROC,
|
||||
IID_IMediaObject,
|
||||
(void **) &m_pObject);
|
||||
if ( FAILED( hr ) ){
|
||||
MessageBox( hDlg, TEXT("Can't create this DMO."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pObject->QueryInterface(IID_IMediaObjectInPlace, (void**)&m_pObjectInPlace);
|
||||
|
||||
// read wave file
|
||||
if( WaveLoadFile( lpszInputFile, (UINT*) &m_uDataSize, &m_pwfx, &m_pbInData ) != 0 ){
|
||||
MessageBox( hDlg, TEXT("Can't load input file."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
if( m_pwfx->wFormatTag != WAVE_FORMAT_PCM ) {
|
||||
MessageBox( hDlg, TEXT("Can't process compressed data."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
|
||||
return E_FAIL;
|
||||
|
||||
}
|
||||
|
||||
m_mt.majortype = MEDIATYPE_Audio;
|
||||
m_mt.subtype = MEDIASUBTYPE_PCM;
|
||||
m_mt.formattype = FORMAT_WaveFormatEx;
|
||||
m_mt.cbFormat = sizeof(WAVEFORMATEX);
|
||||
m_mt.pbFormat = (BYTE*) (m_pwfx);
|
||||
m_mt.pUnk = NULL; // CopyMediaType will crash if we don't intialize this
|
||||
|
||||
hr = m_pObject->SetInputType( 0, //Input Stream index
|
||||
&m_mt,
|
||||
0 ); // No flags specified
|
||||
if ( FAILED( hr ) ){
|
||||
MessageBox( hDlg, TEXT("Can't set input type."), TEXT(DEMO_NAME),MB_OK | MB_ICONERROR );
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_pObject->SetOutputType( 0, // Output Stream Index
|
||||
&m_mt,
|
||||
0); // No flags specified
|
||||
if ( FAILED( hr ) ){
|
||||
MessageBox( hDlg, TEXT("Can't set output type."), TEXT(DEMO_NAME),MB_OK | MB_ICONERROR );
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::Stream()
|
||||
// Desc: called to get the output from DMO
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HRESULT CAppStream::Stream( BYTE **ppbOutData, ULONG *pbDataSize, LPWAVEFORMATEX *ppwfx )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
BYTE *pOut;
|
||||
|
||||
*pbDataSize = m_uDataSize;
|
||||
*ppwfx = m_pwfx;
|
||||
|
||||
if ( m_pObjectInPlace ){
|
||||
|
||||
pOut = new BYTE [m_uDataSize];
|
||||
|
||||
if( pOut == 0 ){
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
CopyMemory(pOut, m_pbInData, m_uDataSize);
|
||||
|
||||
// pass the number of samples to Process()
|
||||
hr = m_pObjectInPlace->Process( m_uDataSize,
|
||||
pOut,
|
||||
0,
|
||||
DMO_INPLACE_NORMAL);
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
*ppbOutData = pOut;
|
||||
SAFE_RELEASE( m_pObjectInPlace );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
CMediaBuffer *pInputBuffer;
|
||||
const REFERENCE_TIME rtStart = 0;
|
||||
const REFERENCE_TIME rtStop = 0;
|
||||
BYTE* pBuffer;
|
||||
DWORD dwLength;
|
||||
|
||||
// create and fill CMediaBuffer
|
||||
hr = CreateBuffer(m_uDataSize, &pInputBuffer);
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
hr = pInputBuffer->GetBufferAndLength( &pBuffer, &dwLength );
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
CopyMemory(pBuffer, m_pbInData, m_uDataSize);
|
||||
hr = pInputBuffer->SetLength( m_uDataSize );
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
|
||||
// call processInput
|
||||
hr = m_pObject->ProcessInput( 0,
|
||||
pInputBuffer,
|
||||
DMO_INPUT_DATA_BUFFERF_SYNCPOINT,
|
||||
rtStart,
|
||||
rtStop - rtStart);
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
|
||||
//release input buffer
|
||||
SAFE_RELEASE( pInputBuffer );
|
||||
|
||||
// retrieve the output data from DMO and put into pOut
|
||||
if(S_FALSE == hr){
|
||||
return E_FAIL;
|
||||
} else {
|
||||
hr = ProcessOutputs( &pOut );
|
||||
if( FAILED( hr ) ){
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
*ppbOutData = pOut;
|
||||
SAFE_RELEASE( m_pObject );
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CAppStream::ProcessOutputs()
|
||||
// Desc: retrieve the output data from DMO
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HRESULT CAppStream::ProcessOutputs( BYTE **ppbOutData )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD dwStatus;
|
||||
ULONG ulSize;
|
||||
BYTE *pOut;
|
||||
|
||||
CMediaBuffer *pOutputBuffer;
|
||||
DMO_OUTPUT_DATA_BUFFER dataBufferStruct;
|
||||
|
||||
hr = CreateBuffer( m_uDataSize,&pOutputBuffer );
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
dataBufferStruct.pBuffer = pOutputBuffer;
|
||||
dataBufferStruct.dwStatus = 0; // No flag is set
|
||||
dataBufferStruct.rtTimestamp = 0; // not used in ProcessOutput()
|
||||
dataBufferStruct.rtTimelength = 0; // not used in ProcessOutput()
|
||||
|
||||
*ppbOutData = new BYTE[m_uDataSize];
|
||||
if( *ppbOutData == 0 ){
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
//process until no more data
|
||||
if (SUCCEEDED(hr)) do {
|
||||
hr = m_pObject->ProcessOutput( DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER,
|
||||
1, //output buffer count
|
||||
&dataBufferStruct,
|
||||
&dwStatus );
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
if( SUCCEEDED(hr) && (hr != S_FALSE) ) {
|
||||
hr = dataBufferStruct.pBuffer->GetBufferAndLength(&pOut, &ulSize);
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
CopyMemory(*ppbOutData, pOut, m_uDataSize);
|
||||
|
||||
hr = dataBufferStruct.pBuffer->SetLength( 0 );
|
||||
if( FAILED( hr ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while ( dataBufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE );
|
||||
|
||||
// free output buffer allocated:
|
||||
SAFE_RELEASE( pOutputBuffer );
|
||||
|
||||
// Send Discontinuity on output stream
|
||||
hr = m_pObject->Discontinuity( 0 );
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: CreateBuffer()
|
||||
// Desc: create a CMediaBuffer
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CreateBuffer(
|
||||
DWORD cbMaxLength,
|
||||
CMediaBuffer **ppBuffer)
|
||||
{
|
||||
CMediaBuffer *pBuffer = new CMediaBuffer( cbMaxLength );
|
||||
if ( pBuffer == NULL || FAILED( pBuffer->Init() ) ) {
|
||||
delete pBuffer;
|
||||
*ppBuffer = NULL;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
*ppBuffer = pBuffer;
|
||||
(*ppBuffer)->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AppStream.h
|
||||
//
|
||||
// Desc: DirectShow sample code - header file for CAppStream class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __APPSTREAM_H__
|
||||
#define __APPSTREAM_H__
|
||||
|
||||
#define DEMO_NAME "DMO Demo"
|
||||
#define SafeGlobalFree(p) if((p)) GlobalFree((p)); \
|
||||
p = NULL
|
||||
|
||||
#pragma warning(disable:4100) // Disable C4100: unreferenced formal parameter
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The following definitions come from the Platform SDK and are required if
|
||||
// the application is being compiled with the headers from Visual C++ 6.0.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifndef GetWindowLongPtr
|
||||
#define GetWindowLongPtrA GetWindowLongA
|
||||
#define GetWindowLongPtrW GetWindowLongW
|
||||
#ifdef UNICODE
|
||||
#define GetWindowLongPtr GetWindowLongPtrW
|
||||
#else
|
||||
#define GetWindowLongPtr GetWindowLongPtrA
|
||||
#endif // !UNICODE
|
||||
#endif // !GetWindowLongPtr
|
||||
|
||||
#ifndef GWLP_HINSTANCE
|
||||
#define GWLP_HINSTANCE (-6)
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// End Platform SDK definitions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
class CMediaBuffer;
|
||||
|
||||
//
|
||||
// CAppStream - reads audio data out of a WAV file, transforms the data using
|
||||
// a user specified DMO and then returns the data to the user in
|
||||
// a memory buffer
|
||||
class CAppStream
|
||||
{
|
||||
public:
|
||||
CAppStream();
|
||||
~CAppStream();
|
||||
|
||||
HRESULT StreamData( LPTSTR lpszFileInput,
|
||||
REFGUID rclsid,
|
||||
HWND hDlg,
|
||||
BYTE **pbOutData,
|
||||
ULONG *cbDataSize,
|
||||
LPWAVEFORMATEX *pwfx );
|
||||
|
||||
private:
|
||||
HRESULT Init(LPTSTR lpszFileInput, REFGUID rclsid, HWND hDlg );
|
||||
HRESULT Stream( BYTE **pbOutData, ULONG *cbDataSize, LPWAVEFORMATEX *pwfx );
|
||||
HRESULT ProcessOutputs( BYTE **pbOutData);
|
||||
|
||||
IMediaObject *m_pObject;
|
||||
IMediaObjectInPlace *m_pObjectInPlace;
|
||||
ULONG m_uDataSize; // Size of input data buffer.
|
||||
LPWAVEFORMATEX m_pwfx; // pointer to input/output waveformatex structure.
|
||||
BYTE* m_pbInData; // Pointer input data buffer read from wave file.
|
||||
DMO_MEDIA_TYPE m_mt;
|
||||
};
|
||||
|
||||
#pragma warning(disable:4512) // C4512: assignment operator could not be generated
|
||||
|
||||
// CMediaBuffer object
|
||||
class CMediaBuffer : public IMediaBuffer
|
||||
{
|
||||
public:
|
||||
CMediaBuffer(DWORD cbMaxLength) :
|
||||
m_cRef(0),
|
||||
m_cbMaxLength(cbMaxLength),
|
||||
m_cbLength(0),
|
||||
m_pbData(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~CMediaBuffer()
|
||||
{
|
||||
if (m_pbData) {
|
||||
delete [] m_pbData;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
|
||||
{
|
||||
if (ppv == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
if (riid == IID_IMediaBuffer || riid == IID_IUnknown) {
|
||||
*ppv = static_cast<IMediaBuffer *>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) Release()
|
||||
{
|
||||
LONG lRef = InterlockedDecrement(&m_cRef);
|
||||
if (lRef == 0) {
|
||||
delete this;
|
||||
}
|
||||
return lRef;
|
||||
}
|
||||
|
||||
STDMETHODIMP SetLength(DWORD cbLength)
|
||||
{
|
||||
if (cbLength > m_cbMaxLength) {
|
||||
return E_INVALIDARG;
|
||||
} else {
|
||||
m_cbLength = cbLength;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP GetMaxLength(DWORD *pcbMaxLength)
|
||||
{
|
||||
if (pcbMaxLength == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
*pcbMaxLength = m_cbMaxLength;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetBufferAndLength(BYTE **ppbBuffer, DWORD *pcbLength)
|
||||
{
|
||||
if (ppbBuffer == NULL || pcbLength == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
*ppbBuffer = m_pbData;
|
||||
*pcbLength = m_cbLength;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Init()
|
||||
{
|
||||
m_pbData = new BYTE[m_cbMaxLength];
|
||||
if (NULL == m_pbData) {
|
||||
return E_OUTOFMEMORY;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD m_cbLength;
|
||||
const DWORD m_cbMaxLength;
|
||||
LONG m_cRef;
|
||||
BYTE *m_pbData;
|
||||
};
|
||||
|
||||
#pragma warning(default:4512) // C4512: assignment operator could not be generated
|
||||
|
||||
HRESULT CreateBuffer( DWORD cbMaxLength, CMediaBuffer **ppBuffer );
|
||||
|
||||
|
||||
|
||||
#endif __APPSTREAM_H__
|
||||
@@ -0,0 +1,81 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Debug.h
|
||||
//
|
||||
// Desc: DirectShow sample code - debug header.
|
||||
//
|
||||
// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __DEBUG_INCLUDED__
|
||||
#define __DEBUG_INCLUDED__
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_SECTION "Debug" // section name for
|
||||
#define DEBUG_MODULE_NAME "DSSHOW" // key name and prefix for output
|
||||
#define DEBUG_MAX_LINE_LEN 255 // max line length (bytes!)
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// based code makes since only in win 16 (to try and keep stuff out of
|
||||
// [fixed] data segments, etc)...
|
||||
//
|
||||
#ifndef BCODE
|
||||
#ifdef _WIN32
|
||||
#define BCODE
|
||||
#else
|
||||
#define BCODE _based(_segname("_CODE"))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
|
||||
//
|
||||
//
|
||||
//
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
|
||||
|
||||
#ifdef DEBUG
|
||||
BOOL WINAPI DbgEnable(BOOL fEnable);
|
||||
UINT WINAPI DbgGetLevel(void);
|
||||
UINT WINAPI DbgSetLevel(UINT uLevel);
|
||||
UINT WINAPI DbgInitialize(BOOL fEnable);
|
||||
void WINAPI _Assert( char * szFile, int iLine );
|
||||
|
||||
void FAR CDECL dprintf(UINT uDbgLevel, LPSTR szFmt, ...);
|
||||
|
||||
#define D(x) {x;}
|
||||
#define DPF dprintf
|
||||
#define DPI(sz) {static char BCODE ach[] = sz; OutputDebugStr(ach);}
|
||||
#define ASSERT(x) if( !(x) ) _Assert( __FILE__, __LINE__)
|
||||
#else
|
||||
#define DbgEnable(x) FALSE
|
||||
#define DbgGetLevel() 0
|
||||
#define DbgSetLevel(x) 0
|
||||
#define DbgInitialize(x) 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4002)
|
||||
#endif
|
||||
|
||||
#define D(x)
|
||||
#define DPF()
|
||||
#define DPI(sz)
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __DEBUG_INCLUDED__
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,483 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// File: DMODemo.cpp
|
||||
//
|
||||
// Desc: The dmodemo sample shows how to stream and playback audio data in a
|
||||
// wave file of reasonable size using DSound Audio Effect DMOs.
|
||||
//
|
||||
// The basic tasks are as follows:
|
||||
// 1) get the wave file name and DMO name selected by the user
|
||||
// 2) call CAppStream::Init() to create the Media Object, get
|
||||
// interface pointer of IMediaObject and IMediaObjectInPlace,if
|
||||
// there is one. Read the wave file into a buffer and read wav format.
|
||||
// 3) call CAppStream::Stream() to process the data using the Media Object,
|
||||
// and retrieve data from the DMO output stream to a buffer in memory.
|
||||
// 4) create the DSound buffer from the buffer which holds the output data
|
||||
// from DMO.
|
||||
// 5) playback the DSound buffer.
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define STRICT
|
||||
#include <TCHAR.h>
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <objbase.h>
|
||||
#include <commdlg.h>
|
||||
#include <dxerr8.h>
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
#include "DSUtil.h"
|
||||
#include "DXUtil.h"
|
||||
#include <dmoreg.h>
|
||||
#include "appstream.h"
|
||||
#include "wave.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function-prototypes
|
||||
//-----------------------------------------------------------------------------
|
||||
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
|
||||
HRESULT InitializeAudioEffectDMOList( HWND hDlg, int* iNumDmo );
|
||||
VOID OnInitDialog( HWND hDlg );
|
||||
VOID OnOpenSoundFile( HWND hDlg );
|
||||
HRESULT StreamData( HWND hDlg, LPTSTR lpszFileInput, REFCLSID rclsid );
|
||||
VOID OnTimer( HWND hDlg );
|
||||
VOID EnablePlayUI( HWND hDlg, BOOL bEnable );
|
||||
VOID ResetSoundBuffer();
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines, constants, and global variables
|
||||
//-----------------------------------------------------------------------------
|
||||
#define MAX_NUM 100
|
||||
#define APPNAME TEXT("DMO Demo")
|
||||
|
||||
|
||||
// struct holding DMOs registerd as DMOCATGORY_AUDIO_EFFECT
|
||||
typedef struct tagDMOINFO {
|
||||
TCHAR szName[MAX_NUM];
|
||||
CLSID clsidDMO;
|
||||
} DMOINFO;
|
||||
|
||||
DMOINFO g_rgDmoInfo[MAX_PATH];
|
||||
TCHAR g_szInputFileName[MAX_PATH];
|
||||
CSoundManager* g_pSoundManager = NULL;
|
||||
CSound* g_pSound = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: WinMain()
|
||||
// Desc: Entry point for the application. Since we use a simple dialog for
|
||||
// user interaction we don't need to pump messages.
|
||||
//-----------------------------------------------------------------------------
|
||||
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine,
|
||||
INT nCmdShow )
|
||||
{
|
||||
// Display the main dialog box.
|
||||
DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: MainDlgProc()
|
||||
// Desc: Handles dialog messages
|
||||
//-----------------------------------------------------------------------------
|
||||
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
int iSelectedDMOIndex =0;
|
||||
HRESULT hr;
|
||||
|
||||
switch( msg )
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
OnInitDialog( hDlg );
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( LOWORD(wParam) )
|
||||
{
|
||||
case IDC_SOUNDFILE:
|
||||
OnOpenSoundFile( hDlg );
|
||||
break;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog( hDlg, IDCANCEL );
|
||||
|
||||
break;
|
||||
|
||||
case IDC_PLAY:
|
||||
iSelectedDMOIndex = ComboBox_GetCurSel( GetDlgItem( hDlg, IDC_DMOCOMBO ) );
|
||||
if( iSelectedDMOIndex < 0 )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("Selecting DMO failed."), TEXT(DEMO_NAME),
|
||||
MB_OK | MB_ICONERROR );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Very large files may take some time to stream, so update the
|
||||
// window title to indicate progress.
|
||||
SetWindowText( hDlg, TEXT("Reading file...") );
|
||||
hr = StreamData( hDlg, g_szInputFileName, g_rgDmoInfo[iSelectedDMOIndex].clsidDMO );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
SetWindowText( hDlg, APPNAME );
|
||||
hr = g_pSound->Play( 0, // lowest priority
|
||||
0 ); // no flag is set
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("Error playing DirectSound buffer.")
|
||||
, TEXT(DEMO_NAME),
|
||||
MB_OK | MB_ICONERROR );
|
||||
}
|
||||
|
||||
EnablePlayUI( hDlg, FALSE );
|
||||
|
||||
break;
|
||||
|
||||
case IDC_STOP:
|
||||
ResetSoundBuffer();
|
||||
EnablePlayUI( hDlg, TRUE );
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE; // Didn't handle message
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_TIMER:
|
||||
OnTimer( hDlg );
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
// Cleanup everything
|
||||
SAFE_DELETE( g_pSound );
|
||||
SAFE_DELETE( g_pSoundManager );
|
||||
KillTimer(hDlg, 1);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE; // Didn't handle message
|
||||
}
|
||||
|
||||
return TRUE; // Handled message
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OnInitDialog()
|
||||
// Desc: Initializes the dialogs (sets up UI controls, etc.)
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID OnInitDialog( HWND hDlg )
|
||||
{
|
||||
int iNumDmo = 0;
|
||||
HRESULT hr;
|
||||
|
||||
// Load the icon
|
||||
HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr( hDlg, GWLP_HINSTANCE );
|
||||
HICON hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDR_DEMOICON ) );
|
||||
|
||||
// Set the icon for this dialog.
|
||||
SendMessage( hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon ); // Set big icon
|
||||
SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon ); // Set small icon
|
||||
|
||||
// get registered DMOs
|
||||
hr = InitializeAudioEffectDMOList( hDlg, &iNumDmo);
|
||||
if( FAILED( hr ) ) {
|
||||
|
||||
MessageBox( hDlg, TEXT("Error enumerating DMOs. "), TEXT(DEMO_NAME),
|
||||
MB_OK | MB_ICONERROR );
|
||||
return;
|
||||
}
|
||||
|
||||
for(int ii = 0; ii <iNumDmo; ii++){
|
||||
ComboBox_AddString(GetDlgItem(hDlg, IDC_DMOCOMBO), g_rgDmoInfo[ii].szName);
|
||||
}
|
||||
ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_DMOCOMBO), 0);
|
||||
|
||||
// CSoundManager creates a CSound buffer.
|
||||
// and sets cooperative level to DSSCL_PRIORITY (See DirectSound documentation for
|
||||
// more iformation), and set primary buffer format to stereo, 22kHz and 16-bit output.
|
||||
g_pSoundManager = new CSoundManager();
|
||||
if( g_pSoundManager == NULL )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("Creating CSoundManager failed."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
EndDialog( hDlg, IDCANCEL );
|
||||
}
|
||||
hr = g_pSoundManager->Initialize( hDlg, DSSCL_PRIORITY, 2, 22050, 16 );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("Error initializing DirectSound."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
EndDialog( hDlg, IDCANCEL );
|
||||
}
|
||||
|
||||
// Set the UI controls
|
||||
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("No file loaded.") );
|
||||
|
||||
// Create a timer, so we can check for when the soundbuffer is stopped
|
||||
SetTimer( hDlg, 0, 250, NULL );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OnOpenSoundFile()
|
||||
// Desc: Called when the user requests to open a sound file
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID OnOpenSoundFile( HWND hDlg )
|
||||
{
|
||||
static TCHAR strFileName[MAX_PATH] = TEXT("");
|
||||
static TCHAR strPath[MAX_PATH] = TEXT("");
|
||||
|
||||
OPENFILENAME ofn;
|
||||
|
||||
// Setup the OPENFILENAME structure
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = hDlg;
|
||||
ofn.hInstance = NULL;
|
||||
ofn.lpstrFilter = TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0");
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.nFilterIndex= 1;
|
||||
ofn.lpstrFile = strFileName;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = strPath;
|
||||
ofn.lpstrTitle = TEXT("Open Sound File");
|
||||
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
||||
ofn.nFileOffset = 0;
|
||||
ofn.nFileExtension = 0;
|
||||
ofn.lpstrDefExt = TEXT(".wav");
|
||||
ofn.lCustData = 0;
|
||||
ofn.lpfnHook = NULL;
|
||||
ofn.lpTemplateName = NULL;
|
||||
|
||||
// Get the default media path (something like C:\WINDOWS\MEDIA)
|
||||
if( '\0' == strPath[0] )
|
||||
{
|
||||
UINT uResult = GetWindowsDirectory( strPath, MAX_PATH );
|
||||
if( uResult == 0 )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("GetWindowsDirectory() failed."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
return;
|
||||
}
|
||||
if( lstrcmp( &strPath[lstrlen(strPath)], TEXT("\\") ) )
|
||||
lstrcat( strPath, TEXT("\\") );
|
||||
lstrcat( strPath, TEXT("MEDIA") );
|
||||
}
|
||||
|
||||
ResetSoundBuffer();
|
||||
|
||||
// Update the UI controls to show the sound as loading a file
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE);
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE);
|
||||
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Loading file...") );
|
||||
|
||||
// Display the OpenFileName dialog. Then, try to load the specified file
|
||||
if( TRUE != GetOpenFileName( &ofn ) )
|
||||
{
|
||||
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Load aborted.") );
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the UI controls to show the sound as the file is loaded
|
||||
SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
|
||||
EnablePlayUI( hDlg, TRUE );
|
||||
|
||||
// Remember the path for next time
|
||||
lstrcpy(g_szInputFileName, strFileName);
|
||||
lstrcpy( strPath, strFileName );
|
||||
|
||||
TCHAR* strLastSlash = _tcsrchr( strPath, '\\' );
|
||||
strLastSlash[0] = '\0';
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OutputDMOs()
|
||||
// Desc: Called to fill the combo box
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT InitializeAudioEffectDMOList( HWND hDlg, int* iNumDmo)
|
||||
{
|
||||
|
||||
IEnumDMO* pEveryRegisterDMOEnum = NULL;
|
||||
HRESULT hrNext;
|
||||
DWORD ulNumInfoReturned;
|
||||
CLSID clsidCurrentDMO;
|
||||
WCHAR* apszDMOName;
|
||||
|
||||
|
||||
// Enumerate all the registered DMOs registered as DMOCATEGORY_AUDIO_EFFECT.
|
||||
HRESULT hr = DMOEnum( DMOCATEGORY_AUDIO_EFFECT,
|
||||
DMO_ENUMF_INCLUDE_KEYED,
|
||||
0, // Number of input partial media types.
|
||||
NULL,
|
||||
0, // Number of output partial media types.
|
||||
NULL,
|
||||
&pEveryRegisterDMOEnum );
|
||||
|
||||
if( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
hrNext = pEveryRegisterDMOEnum->Next( 1, &clsidCurrentDMO, &apszDMOName, &ulNumInfoReturned );
|
||||
if( FAILED( hrNext ) ) {
|
||||
SAFE_RELEASE( pEveryRegisterDMOEnum );
|
||||
return hrNext;
|
||||
}
|
||||
|
||||
if( S_OK == hrNext ) {
|
||||
#ifdef _UNICODE
|
||||
lstrcpy(g_rgDmoInfo[*iNumDmo].szName, apszDMOName );
|
||||
#else
|
||||
TCHAR tempStr[MAX_PATH];
|
||||
int i = wcstombs(tempStr, apszDMOName, MAX_PATH);
|
||||
if( i == -1 )
|
||||
{
|
||||
MessageBox( hDlg, TEXT("wcstombs function encountered a wide character that could not be converted to a multibyte character."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
return E_FAIL;
|
||||
|
||||
}
|
||||
|
||||
lstrcpy(g_rgDmoInfo[*iNumDmo].szName, tempStr );
|
||||
|
||||
#endif
|
||||
|
||||
CoTaskMemFree( apszDMOName );
|
||||
|
||||
g_rgDmoInfo[*iNumDmo].clsidDMO = clsidCurrentDMO;
|
||||
|
||||
(*iNumDmo)++;
|
||||
}
|
||||
|
||||
} while( (S_OK == hrNext) && (*iNumDmo < MAX_NUM) );
|
||||
|
||||
SAFE_RELEASE( pEveryRegisterDMOEnum );
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: StreamData()
|
||||
// Desc: Called when the user requests to Play
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT StreamData( HWND hDlg, LPTSTR lpszInputFile, REFGUID rclsid )
|
||||
{
|
||||
HRESULT hr;
|
||||
BYTE *pbOutData;
|
||||
ULONG uDataSize =0 ;
|
||||
LPWAVEFORMATEX pwfx = NULL; // pointer to waveformatex structure.
|
||||
|
||||
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
|
||||
if( FAILED ( hr ) ) {
|
||||
MessageBox( hDlg, TEXT("Could not initialize COM library."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
return hr;
|
||||
}
|
||||
|
||||
CAppStream* pStream = new CAppStream();
|
||||
if ( !pStream ){
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
hr = pStream->StreamData( lpszInputFile,
|
||||
rclsid,
|
||||
hDlg,
|
||||
&pbOutData,
|
||||
&uDataSize,
|
||||
&pwfx );
|
||||
if ( FAILED( hr ) ) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Free any previous sound, and make a new one
|
||||
SAFE_DELETE( g_pSound );
|
||||
|
||||
// Load the data from memory into a DirectSound buffer
|
||||
hr = g_pSoundManager->CreateFromMemory( &g_pSound, pbOutData,uDataSize, pwfx, DSBCAPS_GLOBALFOCUS, GUID_NULL );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
// Not a critical failure, so just update the status
|
||||
MessageBox( hDlg, TEXT("Could not create sound buffer."),
|
||||
TEXT(DEMO_NAME), MB_OK | MB_ICONERROR );
|
||||
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") );
|
||||
return hr;
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY( pbOutData );
|
||||
SAFE_DELETE ( pStream );
|
||||
SafeGlobalFree( pwfx );
|
||||
|
||||
CoUninitialize();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: OnTimer()
|
||||
// Desc: When we think the sound is playing this periodically checks to see if
|
||||
// the sound has stopped. If it has then updates the dialog.
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID OnTimer( HWND hDlg )
|
||||
{
|
||||
if( IsWindowEnabled( GetDlgItem( hDlg, IDC_STOP ) ) )
|
||||
{
|
||||
// We think the sound is playing, so see if it has stopped yet.
|
||||
if( !g_pSound->IsSoundPlaying() )
|
||||
{
|
||||
// Update the UI controls to show the sound as stopped
|
||||
EnablePlayUI( hDlg, TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: EnablePlayUI( hDlg,)
|
||||
// Desc: Enables or disables the Play UI controls
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID EnablePlayUI( HWND hDlg, BOOL bEnable )
|
||||
{
|
||||
if( bEnable )
|
||||
{
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE );
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), TRUE );
|
||||
SetFocus( GetDlgItem( hDlg, IDC_PLAY ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), TRUE );
|
||||
SetFocus( GetDlgItem( hDlg, IDC_STOP ) );
|
||||
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ResetSoundBuffer()
|
||||
// Desc: called when user click stop button or open file button
|
||||
//-----------------------------------------------------------------------------
|
||||
VOID ResetSoundBuffer()
|
||||
{
|
||||
if( g_pSound )
|
||||
{
|
||||
g_pSound->Stop();
|
||||
g_pSound->Reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
# Microsoft Developer Studio Project File - Name="dmodemo" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=dmodemo - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "dmodemo.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "dmodemo.mak" CFG="dmodemo - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "dmodemo - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "dmodemo - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "dmodemo - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\BaseClasses" /I "..\..\..\common\include" /I "..\..\..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D _WIN32_WINNT=0x0400 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 comctl32.lib dsound.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib amstrmid.lib msdmo.lib dmoguids.lib dxguid.lib shlwapi.lib /nologo /subsystem:windows /machine:I386 /libpath:"..\..\..\..\..\lib" /OPT:NOREF /OPT:ICF /stack:0x200000,0x200000
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "dmodemo - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\BaseClasses" /I "..\..\..\common\include" /I "..\..\..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D _WIN32_WINNT=0x0400 /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 comctl32.lib dsound.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib amstrmid.lib msdmo.lib dmoguids.lib dxguid.lib shlwapi.lib dxerr8.lib /nologo /debug /machine:IX86 /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "dmodemo - Win32 Release"
|
||||
# Name "dmodemo - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\appstream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dmodemo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\wave.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\directx.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dmodemo.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\appstream.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Common"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\src\dsutil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\include\dsutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\src\dxutil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\include\dxutil.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "dmodemo"=.\dmodemo.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Based on dmodemo.dsp
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=dmodemo - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to dmodemo - Win32 Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "dmodemo - Win32 Release" && "$(CFG)" != "dmodemo - Win32 Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "dmodemo.mak" CFG="dmodemo - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "dmodemo - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "dmodemo - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "dmodemo - Win32 Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\dmodemo.exe"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\appstream.obj"
|
||||
-@erase "$(INTDIR)\dmodemo.obj"
|
||||
-@erase "$(INTDIR)\dmodemo.res"
|
||||
-@erase "$(INTDIR)\dsutil.obj"
|
||||
-@erase "$(INTDIR)\dxutil.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\wave.obj"
|
||||
-@erase "$(OUTDIR)\dmodemo.exe"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\BaseClasses" /I "..\..\..\common\include" /I "..\..\..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D _WIN32_WINNT=0x0400 /Fp"$(INTDIR)\dmodemo.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmodemo.res" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\dmodemo.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=comctl32.lib dsound.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib amstrmid.lib msdmo.lib dmoguids.lib dxguid.lib shlwapi.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\dmodemo.pdb" /machine:I386 /out:"$(OUTDIR)\dmodemo.exe" /libpath:"..\..\..\..\..\lib" /OPT:NOREF /OPT:ICF /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\appstream.obj" \
|
||||
"$(INTDIR)\dmodemo.obj" \
|
||||
"$(INTDIR)\wave.obj" \
|
||||
"$(INTDIR)\dsutil.obj" \
|
||||
"$(INTDIR)\dxutil.obj" \
|
||||
"$(INTDIR)\dmodemo.res"
|
||||
|
||||
"$(OUTDIR)\dmodemo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "dmodemo - Win32 Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\dmodemo.exe"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\appstream.obj"
|
||||
-@erase "$(INTDIR)\dmodemo.obj"
|
||||
-@erase "$(INTDIR)\dmodemo.res"
|
||||
-@erase "$(INTDIR)\dsutil.obj"
|
||||
-@erase "$(INTDIR)\dxutil.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(INTDIR)\wave.obj"
|
||||
-@erase "$(OUTDIR)\dmodemo.exe"
|
||||
-@erase "$(OUTDIR)\dmodemo.ilk"
|
||||
-@erase "$(OUTDIR)\dmodemo.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "..\..\BaseClasses" /I "..\..\..\common\include" /I "..\..\..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D _WIN32_WINNT=0x0400 /Fp"$(INTDIR)\dmodemo.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmodemo.res" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\dmodemo.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=comctl32.lib dsound.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib amstrmid.lib msdmo.lib dmoguids.lib dxguid.lib shlwapi.lib dxerr8.lib /nologo /incremental:yes /pdb:"$(OUTDIR)\dmodemo.pdb" /debug /machine:IX86 /out:"$(OUTDIR)\dmodemo.exe" /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\appstream.obj" \
|
||||
"$(INTDIR)\dmodemo.obj" \
|
||||
"$(INTDIR)\wave.obj" \
|
||||
"$(INTDIR)\dsutil.obj" \
|
||||
"$(INTDIR)\dxutil.obj" \
|
||||
"$(INTDIR)\dmodemo.res"
|
||||
|
||||
"$(OUTDIR)\dmodemo.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1"
|
||||
!IF EXISTS("dmodemo.dep")
|
||||
!INCLUDE "dmodemo.dep"
|
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "dmodemo.dep"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "dmodemo - Win32 Release" || "$(CFG)" == "dmodemo - Win32 Debug"
|
||||
SOURCE=.\appstream.cpp
|
||||
|
||||
"$(INTDIR)\appstream.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\dmodemo.cpp
|
||||
|
||||
"$(INTDIR)\dmodemo.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\wave.c
|
||||
|
||||
"$(INTDIR)\wave.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\dmodemo.rc
|
||||
|
||||
"$(INTDIR)\dmodemo.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) $(RSC_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\..\Common\src\dsutil.cpp
|
||||
|
||||
"$(INTDIR)\dsutil.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\..\Common\src\dxutil.cpp
|
||||
|
||||
"$(INTDIR)\dxutil.obj" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_OLE_RESOURCES\r\n"
|
||||
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
|
||||
"\r\n"
|
||||
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
|
||||
"#ifdef _WIN32\r\n"
|
||||
"LANGUAGE 9, 1\r\n"
|
||||
"#pragma code_page(1252)\r\n"
|
||||
"#endif\r\n"
|
||||
"#include ""afxres.rc"" // Standard components\r\n"
|
||||
"#endif\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_DEMOICON ICON DISCARDABLE "directx.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_MAIN DIALOGEX 0, 0, 260, 65
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
|
||||
WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "DMO Demo"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Sound &file...",IDC_SOUNDFILE,7,7,46,13
|
||||
LTEXT "",IDC_FILENAME,68,7,185,13,SS_CENTERIMAGE,
|
||||
WS_EX_CLIENTEDGE
|
||||
LTEXT "Select &DMO:",IDC_SELECTDMO,7,30,58,8
|
||||
COMBOBOX IDC_DMOCOMBO,68,26,185,183,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
PUSHBUTTON "&Play",IDC_PLAY,28,44,50,14,WS_DISABLED
|
||||
PUSHBUTTON "&Stop",IDC_STOP,93,44,50,14,WS_DISABLED
|
||||
PUSHBUTTON "E&xit",IDCANCEL,190,44,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_MAIN, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 253
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 58
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE
|
||||
BEGIN
|
||||
"F", IDC_SOUNDFILE, VIRTKEY, ALT, NOINVERT
|
||||
"P", IDC_PLAY, VIRTKEY, ALT, NOINVERT
|
||||
"S", IDC_STOP, VIRTKEY, ALT, NOINVERT
|
||||
"X", IDCANCEL, VIRTKEY, ALT, NOINVERT
|
||||
"D", IDC_SELECTDMO, VIRTKEY, ALT, NOINVERT
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "DMO Demo Applicatoin\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "DMODemo\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "DMODemo.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "DirectX 8 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#define _AFX_NO_SPLITTER_RESOURCES
|
||||
#define _AFX_NO_OLE_RESOURCES
|
||||
#define _AFX_NO_TRACKER_RESOURCES
|
||||
#define _AFX_NO_PROPERTY_RESOURCES
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE 9, 1
|
||||
#pragma code_page(1252)
|
||||
#endif
|
||||
#include "afxres.rc" // Standard components
|
||||
#endif
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
DirectShow Sample -- DMODemo
|
||||
----------------------------
|
||||
|
||||
Description
|
||||
===========
|
||||
This sample application demonstrates how to use Microsoft DirectX Media
|
||||
Objects (DMO). It streams audio data from a WAV file through a DirectSound
|
||||
Audio Effect DMO to a DirectSound buffer.
|
||||
|
||||
For DMOs which are processing data with one input and one output, where the
|
||||
media types of the input and output are the same, and the processing can be
|
||||
done in place, the IMediaObjectInPlace interface can be used. If a DMO
|
||||
supports this interface, DMODemo will call process() on this interface to
|
||||
process the data in place; otherwise, DMODemo will use methods of IMediaObject
|
||||
to process the data.
|
||||
|
||||
|
||||
User's Guide
|
||||
============
|
||||
The sample application includes a project workspace for Microsoft Visual
|
||||
Studio 6.0. For information on setting up your build environment, see
|
||||
"Setting Up the Build Environment" in the DirectX8 SDK documentation.
|
||||
The project file builds dmodemo.exe. The user can load wave files,
|
||||
select a DSound Audio Effect DMO, and play audio using the dialog controls.
|
||||
|
||||
Notes
|
||||
=====
|
||||
For this release, the WavesReverb DMO will only accept 16-bit audio input. If you
|
||||
attempt to connect the WavesReverb DMO to an 8-bit audio source, you will see an
|
||||
error dialog describing a failure to set the input type.
|
||||
@@ -0,0 +1,24 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by dmodemo.rc
|
||||
//
|
||||
#define IDR_DEMOICON 128
|
||||
#define IDD_MAIN 130
|
||||
#define IDC_PLAY 1000
|
||||
#define IDC_STOP 1001
|
||||
#define IDC_SOUNDFILE 1011
|
||||
#define IDC_FILENAME 1015
|
||||
#define IDC_DMOCOMBO 1019
|
||||
#define IDC_SELECTDMO 1020
|
||||
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 132
|
||||
#define _APS_NEXT_COMMAND_VALUE 32772
|
||||
#define _APS_NEXT_CONTROL_VALUE 1027
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
902
Library/dxx8/samples/Multimedia/DirectShow/DMO/DMODemo/wave.c
Normal file
902
Library/dxx8/samples/Multimedia/DirectShow/DMO/DMODemo/wave.c
Normal file
@@ -0,0 +1,902 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Wave.c
|
||||
//
|
||||
// Desc: DirectShow sample code - Wave library routines.
|
||||
//
|
||||
// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*==========================================================================
|
||||
*
|
||||
* This file is used for loading/saving waves, and reading and
|
||||
* writing waves in smaller blocks.
|
||||
* Uses WaveOpenFile, WaveReadFile and WaveCloseReadFile for
|
||||
* single block access to reading wave files.
|
||||
* Uses WaveCreateFile, WaveWriteFile, WaveCloseWriteFile for
|
||||
* single block access for writing wave files.
|
||||
* Uses WaveLoadFile to load a whole wave file into memory.
|
||||
* Uses WaveSaveFile to save a whole wave file into memory.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#pragma warning(disable:4100) // Disable C4100: unreferenced formal parameter
|
||||
#pragma warning(disable:4213) // Disable C4213: cast on lvalue
|
||||
#pragma warning(disable:4115) // Disable C4115: (from VC6.0 header rpsasync.h)
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "wave.h"
|
||||
#include "debug.h"
|
||||
#include "windowsx.h"
|
||||
|
||||
#pragma warning(default:4115) // Reset to default behavior for C4115
|
||||
|
||||
|
||||
/* ROUTINES */
|
||||
/* -------------------------------------------------------*/
|
||||
|
||||
/* This function will open a wave input file and prepare it for reading,
|
||||
* so the data can be easily
|
||||
* read with WaveReadFile. Returns 0 if successful, the error code if not.
|
||||
* pszFileName - Input filename to load.
|
||||
* phmmioIn - Pointer to handle which will be used
|
||||
* for further mmio routines.
|
||||
* ppwfxInfo - Ptr to ptr to WaveFormatEx structure
|
||||
* with all info about the file.
|
||||
*
|
||||
*/
|
||||
int WaveOpenFile(
|
||||
TCHAR*pszFileName, // (IN)
|
||||
HMMIO *phmmioIn, // (OUT)
|
||||
WAVEFORMATEX **ppwfxInfo, // (OUT)
|
||||
MMCKINFO *pckInRIFF // (OUT)
|
||||
)
|
||||
{
|
||||
HMMIO hmmioIn;
|
||||
MMCKINFO ckIn; // chunk info. for general use.
|
||||
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
|
||||
WORD cbExtraAlloc; // Extra bytes for waveformatex
|
||||
int nError; // Return value.
|
||||
|
||||
|
||||
// Initialization...
|
||||
*ppwfxInfo = NULL;
|
||||
nError = 0;
|
||||
hmmioIn = NULL;
|
||||
|
||||
if ((hmmioIn = mmioOpen(pszFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL)
|
||||
{
|
||||
nError = ER_CANNOTOPEN;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
if ((nError = (int)mmioDescend(hmmioIn, pckInRIFF, NULL, 0)) != 0)
|
||||
{
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
|
||||
if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')))
|
||||
{
|
||||
nError = ER_NOTWAVEFILE;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
/* Search the input file for for the 'fmt ' chunk. */
|
||||
ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
|
||||
if ((nError = (int)mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0)
|
||||
{
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
/* Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
|
||||
* if there are extra parameters at the end, we'll ignore them */
|
||||
|
||||
if (ckIn.cksize < (long) sizeof(PCMWAVEFORMAT))
|
||||
{
|
||||
nError = ER_NOTWAVEFILE;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
/* Read the 'fmt ' chunk into <pcmWaveFormat>.*/
|
||||
if (mmioRead(hmmioIn, (HPSTR) &pcmWaveFormat, (long) sizeof(pcmWaveFormat)) != (long) sizeof(pcmWaveFormat))
|
||||
{
|
||||
nError = ER_CANNOTREAD;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
|
||||
// Ok, allocate the waveformatex, but if its not pcm
|
||||
// format, read the next word, and thats how many extra
|
||||
// bytes to allocate.
|
||||
if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
|
||||
cbExtraAlloc = 0;
|
||||
|
||||
else
|
||||
{
|
||||
// Read in length of extra bytes.
|
||||
if (mmioRead(hmmioIn, (HPSTR) &cbExtraAlloc,
|
||||
(long) sizeof(cbExtraAlloc)) != (long) sizeof(cbExtraAlloc))
|
||||
{
|
||||
nError = ER_CANNOTREAD;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Ok, now allocate that waveformatex structure.
|
||||
if ((*ppwfxInfo = GlobalAlloc(GMEM_FIXED, sizeof(WAVEFORMATEX)+cbExtraAlloc)) == NULL)
|
||||
{
|
||||
nError = ER_MEM;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
// Copy the bytes from the pcm structure to the waveformatex structure
|
||||
memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
|
||||
(*ppwfxInfo)->cbSize = cbExtraAlloc;
|
||||
|
||||
// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
|
||||
if (cbExtraAlloc != 0)
|
||||
{
|
||||
if (mmioRead(hmmioIn, (HPSTR) (((BYTE*)&((*ppwfxInfo)->cbSize))+sizeof(cbExtraAlloc)),
|
||||
(long) (cbExtraAlloc)) != (long) (cbExtraAlloc))
|
||||
{
|
||||
nError = ER_NOTWAVEFILE;
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ascend the input file out of the 'fmt ' chunk. */
|
||||
if ((nError = mmioAscend(hmmioIn, &ckIn, 0)) != 0)
|
||||
{
|
||||
goto ERROR_READING_WAVE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
goto TEMPCLEANUP;
|
||||
|
||||
ERROR_READING_WAVE:
|
||||
if (*ppwfxInfo != NULL)
|
||||
{
|
||||
GlobalFree(*ppwfxInfo);
|
||||
*ppwfxInfo = NULL;
|
||||
}
|
||||
|
||||
if (hmmioIn != NULL)
|
||||
{
|
||||
mmioClose(hmmioIn, 0);
|
||||
hmmioIn = NULL;
|
||||
}
|
||||
|
||||
TEMPCLEANUP:
|
||||
*phmmioIn = hmmioIn;
|
||||
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
/* This routine has to be called before WaveReadFile as it searchs for the chunk to descend into for
|
||||
reading, that is, the 'data' chunk. For simplicity, this used to be in the open routine, but was
|
||||
taken out and moved to a separate routine so there was more control on the chunks that are before
|
||||
the data chunk, such as 'fact', etc... */
|
||||
|
||||
int WaveStartDataRead(
|
||||
HMMIO *phmmioIn,
|
||||
MMCKINFO *pckIn,
|
||||
MMCKINFO *pckInRIFF
|
||||
)
|
||||
{
|
||||
int nError;
|
||||
|
||||
nError = 0;
|
||||
|
||||
// Do a nice little seek...
|
||||
if ((nError = mmioSeek(*phmmioIn, pckInRIFF->dwDataOffset + sizeof(FOURCC), SEEK_SET)) == -1)
|
||||
{
|
||||
// ASSERT(FALSE);
|
||||
}
|
||||
|
||||
nError = 0;
|
||||
// Search the input file for for the 'data' chunk.
|
||||
pckIn->ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||
if ((nError = mmioDescend(*phmmioIn, pckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0)
|
||||
{
|
||||
goto ERROR_READING_WAVE;
|
||||
}
|
||||
|
||||
goto CLEANUP;
|
||||
|
||||
ERROR_READING_WAVE:
|
||||
|
||||
CLEANUP:
|
||||
return(nError);
|
||||
}
|
||||
|
||||
|
||||
/* This will read wave data from the wave file. Makre sure we're descended into
|
||||
the data chunk, else this will fail bigtime!
|
||||
hmmioIn - Handle to mmio.
|
||||
cbRead - # of bytes to read.
|
||||
pbDest - Destination buffer to put bytes.
|
||||
cbActualRead- # of bytes actually read.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int WaveReadFile(
|
||||
HMMIO hmmioIn, // IN
|
||||
UINT cbRead, // IN
|
||||
BYTE *pbDest, // IN
|
||||
MMCKINFO *pckIn, // IN.
|
||||
UINT *cbActualRead // OUT.
|
||||
|
||||
)
|
||||
{
|
||||
|
||||
MMIOINFO mmioinfoIn; // current status of <hmmioIn>
|
||||
int nError;
|
||||
UINT cT, cbDataIn;
|
||||
|
||||
nError = 0;
|
||||
|
||||
if ((nError = mmioGetInfo(hmmioIn, &mmioinfoIn, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_READ;
|
||||
}
|
||||
|
||||
cbDataIn = cbRead;
|
||||
if (cbDataIn > pckIn->cksize)
|
||||
cbDataIn = pckIn->cksize;
|
||||
|
||||
pckIn->cksize -= cbDataIn;
|
||||
|
||||
for (cT = 0; cT < cbDataIn; cT++)
|
||||
{
|
||||
/* Copy the bytes from the io to the buffer. */
|
||||
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
|
||||
{
|
||||
if ((nError = mmioAdvance(hmmioIn, &mmioinfoIn, MMIO_READ)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_READ;
|
||||
}
|
||||
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
|
||||
{
|
||||
nError = ER_CORRUPTWAVEFILE;
|
||||
goto ERROR_CANNOT_READ;
|
||||
}
|
||||
}
|
||||
|
||||
// Actual copy.
|
||||
*((BYTE*)pbDest+cT) = *((BYTE*)mmioinfoIn.pchNext)++;
|
||||
}
|
||||
|
||||
if ((nError = mmioSetInfo(hmmioIn, &mmioinfoIn, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_READ;
|
||||
}
|
||||
|
||||
*cbActualRead = cbDataIn;
|
||||
goto FINISHED_READING;
|
||||
|
||||
ERROR_CANNOT_READ:
|
||||
*cbActualRead = 0;
|
||||
|
||||
FINISHED_READING:
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
/* This will close the wave file openned with WaveOpenFile.
|
||||
phmmioIn - Pointer to the handle to input MMIO.
|
||||
ppwfxSrc - Pointer to pointer to WaveFormatEx structure.
|
||||
|
||||
Returns 0 if successful, non-zero if there was a warning.
|
||||
|
||||
*/
|
||||
int WaveCloseReadFile(
|
||||
HMMIO *phmmio, // IN
|
||||
WAVEFORMATEX **ppwfxSrc // IN
|
||||
)
|
||||
{
|
||||
|
||||
if (*ppwfxSrc != NULL)
|
||||
{
|
||||
GlobalFree(*ppwfxSrc);
|
||||
*ppwfxSrc = NULL;
|
||||
}
|
||||
|
||||
if (*phmmio != NULL)
|
||||
{
|
||||
mmioClose(*phmmio, 0);
|
||||
*phmmio = NULL;
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
/* This routine will create a wave file for writing. This will automatically overwrite any
|
||||
existing file with the same name, so be careful and check before hand!!!
|
||||
pszFileName - Pointer to filename to write.
|
||||
phmmioOut - Pointer to HMMIO handle that is used for further writes
|
||||
pwfxDest - Valid waveformatex destination structure.
|
||||
pckOut - Pointer to be set with the MMCKINFO.
|
||||
pckOutRIFF - Pointer to be set with the RIFF info.
|
||||
|
||||
*/
|
||||
int WaveCreateFile(
|
||||
TCHAR*pszFileName, // (IN)
|
||||
HMMIO *phmmioOut, // (OUT)
|
||||
WAVEFORMATEX *pwfxDest, // (IN)
|
||||
MMCKINFO *pckOut, // (OUT)
|
||||
MMCKINFO *pckOutRIFF // (OUT)
|
||||
|
||||
)
|
||||
{
|
||||
|
||||
int nError; // Return value.
|
||||
DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile.
|
||||
MMCKINFO ckOut1;
|
||||
|
||||
dwFactChunk = (DWORD)-1;
|
||||
nError = 0;
|
||||
|
||||
*phmmioOut = mmioOpen(pszFileName, NULL,
|
||||
MMIO_ALLOCBUF | MMIO_READWRITE|MMIO_CREATE);
|
||||
|
||||
if (*phmmioOut == NULL)
|
||||
{
|
||||
nError = ER_CANNOTWRITE;
|
||||
goto ERROR_CANNOT_WRITE; // cannot save WAVE file
|
||||
}
|
||||
|
||||
/* Create the output file RIFF chunk of form type 'WAVE'.
|
||||
*/
|
||||
pckOutRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
|
||||
pckOutRIFF->cksize = 0;
|
||||
if ((nError = mmioCreateChunk(*phmmioOut, pckOutRIFF, MMIO_CREATERIFF)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
/* We are now descended into the 'RIFF' chunk we just created.
|
||||
* Now create the 'fmt ' chunk. Since we know the size of this chunk,
|
||||
* specify it in the MMCKINFO structure so MMIO doesn't have to seek
|
||||
* back and set the chunk size after ascending from the chunk.
|
||||
*/
|
||||
pckOut->ckid = mmioFOURCC('f', 'm', 't', ' ');
|
||||
pckOut->cksize = sizeof(PCMWAVEFORMAT); // we know the size of this ck.
|
||||
if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
/* Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. */
|
||||
if (pwfxDest->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
if (mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(PCMWAVEFORMAT))
|
||||
!= sizeof(PCMWAVEFORMAT))
|
||||
{
|
||||
nError = ER_CANNOTWRITE;
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Write the variable length size.
|
||||
if ((UINT)mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(*pwfxDest)+pwfxDest->cbSize)
|
||||
!= (sizeof(*pwfxDest)+pwfxDest->cbSize))
|
||||
{
|
||||
nError = ER_CANNOTWRITE;
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
|
||||
*/
|
||||
if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
// Now create the fact chunk, not required for PCM but nice to have. This is filled
|
||||
// in when the close routine is called.
|
||||
ckOut1.ckid = mmioFOURCC('f', 'a', 'c', 't');
|
||||
ckOut1.cksize = 0;
|
||||
if ((nError = mmioCreateChunk(*phmmioOut, &ckOut1, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
if (mmioWrite(*phmmioOut, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) != sizeof(dwFactChunk))
|
||||
{
|
||||
nError = ER_CANNOTWRITE;
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
|
||||
// Now ascend out of the fact chunk...
|
||||
if ((nError = mmioAscend(*phmmioOut, &ckOut1, 0)) != 0)
|
||||
{
|
||||
nError = ER_CANNOTWRITE; // cannot write file, probably
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
goto DONE_CREATE;
|
||||
|
||||
ERROR_CANNOT_WRITE:
|
||||
// Maybe delete the half-written file? Ah forget it for now, its good to leave the
|
||||
// file there for debugging...
|
||||
|
||||
DONE_CREATE:
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
/* This routine has to be called before any data is written to the wave output file, via wavewritefile. This
|
||||
sets up the data to write, and creates the data chunk.
|
||||
*/
|
||||
|
||||
int WaveStartDataWrite(
|
||||
HMMIO *phmmioOut, // (IN)
|
||||
MMCKINFO *pckOut, // (IN)
|
||||
MMIOINFO *pmmioinfoOut // (OUT)
|
||||
)
|
||||
{
|
||||
|
||||
int nError;
|
||||
|
||||
nError = 0;
|
||||
/* Create the 'data' chunk that holds the waveform samples. */
|
||||
pckOut->ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||
pckOut->cksize = 0;
|
||||
if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
}
|
||||
|
||||
if ((nError = mmioGetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
|
||||
goto CLEANUP;
|
||||
ERROR_CANNOT_WRITE:
|
||||
|
||||
CLEANUP:
|
||||
return(nError);
|
||||
}
|
||||
|
||||
/* This routine will write out data to a wave file.
|
||||
hmmioOut - Handle to hmmioOut filled by WaveCreateFile
|
||||
cbWrite - # of bytes to write out.
|
||||
pbSrc - Pointer to source.
|
||||
pckOut - pointer to ckOut filled by WaveCreateFile
|
||||
cbActualWrite - # of actual bytes written.
|
||||
pmmioinfoOut - Pointer to mmioinfoOut filled by WaveCreateFile.
|
||||
|
||||
Returns 0 if successful, else the error code.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int WaveWriteFile(
|
||||
HMMIO hmmioOut, // (IN)
|
||||
UINT cbWrite, // (IN)
|
||||
BYTE *pbSrc, // (IN)
|
||||
MMCKINFO *pckOut, // (IN)
|
||||
UINT *cbActualWrite, // (OUT)
|
||||
MMIOINFO *pmmioinfoOut // (IN)
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
int nError;
|
||||
UINT cT;
|
||||
|
||||
nError = 0;
|
||||
*cbActualWrite = 0;
|
||||
|
||||
for (cT=0; cT < cbWrite; cT++)
|
||||
{
|
||||
if (pmmioinfoOut->pchNext == pmmioinfoOut->pchEndWrite)
|
||||
{
|
||||
pmmioinfoOut->dwFlags |= MMIO_DIRTY;
|
||||
if ((nError = mmioAdvance(hmmioOut, pmmioinfoOut, MMIO_WRITE)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
}
|
||||
*((BYTE*)pmmioinfoOut->pchNext)++ = *((BYTE*)pbSrc+cT);
|
||||
(*cbActualWrite)++;
|
||||
}
|
||||
|
||||
|
||||
ERROR_CANNOT_WRITE:
|
||||
// What to do here? Well, for now, nothing, just return that error. (maybe delete the
|
||||
// file later?
|
||||
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This routine will close a wave file used for writing. Returns 0 if successful, else
|
||||
the error code.
|
||||
phmmioOut - Pointer to mmio handle for saving.
|
||||
pckOut - Pointer to the MMCKINFO for saving.
|
||||
pckOutRiff - Pointer to the riff MMCKINFO for saving.
|
||||
pmmioinfoOut- Pointer to mmioinfo for saving.
|
||||
cSamples - # of samples saved, for the fact chunk. For PCM, this isn't used but
|
||||
will be written anyway, so this can be zero as long as programs ignore
|
||||
this field when they load PCM formats.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
int WaveCloseWriteFile(
|
||||
HMMIO *phmmioOut, // (IN)
|
||||
MMCKINFO *pckOut, // (IN)
|
||||
MMCKINFO *pckOutRIFF, // (IN)
|
||||
MMIOINFO *pmmioinfoOut, // (IN)
|
||||
DWORD cSamples // (IN)
|
||||
)
|
||||
{
|
||||
|
||||
int nError;
|
||||
|
||||
nError = 0;
|
||||
|
||||
if (*phmmioOut == NULL)
|
||||
return(0);
|
||||
|
||||
pmmioinfoOut->dwFlags |= MMIO_DIRTY;
|
||||
if ((nError = mmioSetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0)
|
||||
{
|
||||
// cannot flush, probably...
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
|
||||
/* Ascend the output file out of the 'data' chunk -- this will cause
|
||||
* the chunk size of the 'data' chunk to be written.
|
||||
*/
|
||||
if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0)
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
|
||||
|
||||
// Do this here instead...
|
||||
if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0)
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
|
||||
|
||||
nError = mmioSeek(*phmmioOut, 0, SEEK_SET);
|
||||
if ((nError = (int)mmioDescend(*phmmioOut, pckOutRIFF, NULL, 0)) != 0)
|
||||
{
|
||||
goto ERROR_CANNOT_WRITE;
|
||||
}
|
||||
|
||||
nError = 0;
|
||||
pckOut->ckid = mmioFOURCC('f', 'a', 'c', 't');
|
||||
if ((nError = mmioDescend(*phmmioOut, pckOut, pckOutRIFF, MMIO_FINDCHUNK)) == 0)
|
||||
{
|
||||
// If it didn't fail, write the fact chunk out, if it failed, not critical, just
|
||||
// assert (below).
|
||||
nError = mmioWrite(*phmmioOut, (HPSTR)&cSamples, sizeof(DWORD));
|
||||
nError = mmioAscend(*phmmioOut, pckOut, 0);
|
||||
nError = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nError = 0;
|
||||
// ASSERT(FALSE);
|
||||
}
|
||||
|
||||
// CANTWRITEFACT:
|
||||
/* Ascend the output file out of the 'RIFF' chunk -- this will cause
|
||||
* the chunk size of the 'RIFF' chunk to be written.
|
||||
*/
|
||||
if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0)
|
||||
goto ERROR_CANNOT_WRITE; // cannot write file, probably
|
||||
|
||||
|
||||
|
||||
ERROR_CANNOT_WRITE:
|
||||
if (*phmmioOut != NULL)
|
||||
{
|
||||
mmioClose(*phmmioOut, 0);
|
||||
*phmmioOut = NULL;
|
||||
}
|
||||
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
/* This routine will copy from a source wave file to a destination wave file all those useless chunks
|
||||
(well, the ones useless to conversions, etc --> apparently people use them!). The source will be
|
||||
seeked to the begining, but the destination has to be at a current pointer to put the new chunks.
|
||||
This will also seek back to the start of the wave riff header at the end of the routine.
|
||||
|
||||
phmmioIn - Pointer to input mmio file handle.
|
||||
pckIn - Pointer to a nice ckIn to use.
|
||||
pckInRiff - Pointer to the main riff.
|
||||
phmmioOut - Pointer to output mmio file handle.
|
||||
pckOut - Pointer to nice ckOut to use.
|
||||
pckOutRiff - Pointer to the main riff.
|
||||
|
||||
|
||||
Returns 0 if successful, else the error code. If this routine fails, it still attemps to seek back to
|
||||
the start of the wave riff header, though this too could be unsuccessful.
|
||||
*/
|
||||
|
||||
int WaveCopyUselessChunks(
|
||||
HMMIO *phmmioIn,
|
||||
MMCKINFO *pckIn,
|
||||
MMCKINFO *pckInRiff,
|
||||
HMMIO *phmmioOut,
|
||||
MMCKINFO *pckOut,
|
||||
MMCKINFO *pckOutRiff)
|
||||
{
|
||||
int nError;
|
||||
|
||||
nError = 0;
|
||||
// First seek to the stinking start of the file, not including the riff header...
|
||||
if ((nError = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET)) == -1)
|
||||
{
|
||||
nError = ER_CANNOTREAD;
|
||||
goto ERROR_IN_PROC;
|
||||
}
|
||||
|
||||
nError = 0;
|
||||
|
||||
while (mmioDescend(*phmmioIn, pckIn, pckInRiff, 0) == 0)
|
||||
{
|
||||
|
||||
// quickly check for corrupt RIFF file--don't ascend past end!
|
||||
if ((pckIn->dwDataOffset + pckIn->cksize) > (pckInRiff->dwDataOffset + pckInRiff->cksize))
|
||||
goto ERROR_IN_PROC;
|
||||
|
||||
switch (pckIn->ckid)
|
||||
{
|
||||
// explicitly skip these...
|
||||
case mmioFOURCC('f', 'm', 't', ' '):
|
||||
break;
|
||||
|
||||
case mmioFOURCC('d', 'a', 't', 'a'):
|
||||
break;
|
||||
|
||||
case mmioFOURCC('f', 'a', 'c', 't'):
|
||||
break;
|
||||
|
||||
case mmioFOURCC('J', 'U', 'N', 'K'):
|
||||
break;
|
||||
|
||||
case mmioFOURCC('P', 'A', 'D', ' '):
|
||||
break;
|
||||
|
||||
case mmioFOURCC('c', 'u', 'e', ' '):
|
||||
break;
|
||||
|
||||
// copy chunks that are OK to copy
|
||||
case mmioFOURCC('p', 'l', 's', 't'):
|
||||
// although without the 'cue' chunk, it doesn't make much sense
|
||||
riffCopyChunk(*phmmioIn, *phmmioOut, pckIn);
|
||||
break;
|
||||
|
||||
case mmioFOURCC('D', 'I', 'S', 'P'):
|
||||
riffCopyChunk(*phmmioIn, *phmmioOut, pckIn);
|
||||
break;
|
||||
|
||||
|
||||
// don't copy unknown chunks
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// step up to prepare for next chunk..
|
||||
mmioAscend(*phmmioIn, pckIn, 0);
|
||||
}
|
||||
|
||||
ERROR_IN_PROC:
|
||||
{
|
||||
int nErrorT;
|
||||
// Seek back to riff header
|
||||
nErrorT = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET);
|
||||
}
|
||||
|
||||
return(nError);
|
||||
}
|
||||
|
||||
/** BOOL RIFFAPI riffCopyChunk(HMMIO hmmioSrc, HMMIO hmmioDst, const LPMMCKINFO lpck)
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
*
|
||||
* ARGUMENTS:
|
||||
* (LPWAVECONVCB lpwc, LPMMCKINFO lpck)
|
||||
*
|
||||
* RETURN (BOOL NEAR PASCAL):
|
||||
*
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
** */
|
||||
|
||||
BOOL riffCopyChunk(HMMIO hmmioSrc, HMMIO hmmioDst, const LPMMCKINFO lpck)
|
||||
{
|
||||
MMCKINFO ck;
|
||||
HPSTR hpBuf;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
hpBuf = (HPSTR)GlobalAllocPtr(GHND, lpck->cksize);
|
||||
if (!hpBuf)
|
||||
return (FALSE);
|
||||
|
||||
ck.ckid = lpck->ckid;
|
||||
ck.cksize = lpck->cksize;
|
||||
if (mmioCreateChunk(hmmioDst, &ck, 0))
|
||||
goto rscc_Error;
|
||||
|
||||
if (mmioRead(hmmioSrc, hpBuf, lpck->cksize) != (LONG)lpck->cksize)
|
||||
goto rscc_Error;
|
||||
|
||||
if (mmioWrite(hmmioDst, hpBuf, lpck->cksize) != (LONG)lpck->cksize)
|
||||
goto rscc_Error;
|
||||
|
||||
if (mmioAscend(hmmioDst, &ck, 0))
|
||||
goto rscc_Error;
|
||||
|
||||
if (hpBuf)
|
||||
GlobalFreePtr(hpBuf);
|
||||
|
||||
return (TRUE);
|
||||
|
||||
rscc_Error:
|
||||
|
||||
if (hpBuf)
|
||||
GlobalFreePtr(hpBuf);
|
||||
|
||||
return (FALSE);
|
||||
} /* RIFFSupCopyChunk() */
|
||||
|
||||
|
||||
|
||||
/* This routine loads a full wave file into memory. Be careful, wave files can get
|
||||
pretty big these days :).
|
||||
szFileName - sz Filename
|
||||
cbSize - Size of loaded wave (returned)
|
||||
cSamples - # of samples loaded.
|
||||
ppwfxInfo - Pointer to pointer to waveformatex structure. The wfx structure
|
||||
IS ALLOCATED by this routine! Make sure to free it!
|
||||
ppbData - Pointer to a byte pointer (globalalloc) which is allocated by this
|
||||
routine. Make sure to free it!
|
||||
|
||||
Returns 0 if successful, else the error code.
|
||||
*/
|
||||
|
||||
int WaveLoadFile(
|
||||
TCHAR*pszFileName, // (IN)
|
||||
UINT *cbSize, // (OUT)
|
||||
WAVEFORMATEX **ppwfxInfo, // (OUT)
|
||||
BYTE **ppbData // (OUT)
|
||||
)
|
||||
{
|
||||
|
||||
HMMIO hmmioIn;
|
||||
MMCKINFO ckInRiff;
|
||||
MMCKINFO ckIn;
|
||||
int nError;
|
||||
UINT cbActualRead;
|
||||
|
||||
*ppbData = NULL;
|
||||
*ppwfxInfo = NULL;
|
||||
*cbSize = 0;
|
||||
|
||||
if ((nError = WaveOpenFile(pszFileName, &hmmioIn, ppwfxInfo, &ckInRiff)) != 0)
|
||||
{
|
||||
goto ERROR_LOADING;
|
||||
}
|
||||
|
||||
if ((nError = WaveStartDataRead(&hmmioIn, &ckIn, &ckInRiff)) != 0)
|
||||
{
|
||||
goto ERROR_LOADING;
|
||||
}
|
||||
|
||||
// Ok, size of wave data is in ckIn, allocate that buffer.
|
||||
if ((*ppbData = (BYTE *)GlobalAlloc(GMEM_FIXED, ckIn.cksize)) == NULL)
|
||||
{
|
||||
nError = ER_MEM;
|
||||
goto ERROR_LOADING;
|
||||
}
|
||||
|
||||
if ((nError = WaveReadFile(hmmioIn, ckIn.cksize, *ppbData, &ckIn, &cbActualRead)) != 0)
|
||||
{
|
||||
goto ERROR_LOADING;
|
||||
}
|
||||
|
||||
*cbSize = cbActualRead;
|
||||
goto DONE_LOADING;
|
||||
|
||||
ERROR_LOADING:
|
||||
if (*ppbData != NULL)
|
||||
{
|
||||
GlobalFree(*ppbData);
|
||||
*ppbData = NULL;
|
||||
}
|
||||
if (*ppwfxInfo != NULL)
|
||||
{
|
||||
GlobalFree(*ppwfxInfo);
|
||||
*ppwfxInfo = NULL;
|
||||
}
|
||||
|
||||
DONE_LOADING:
|
||||
// Close the wave file.
|
||||
if (hmmioIn != NULL)
|
||||
{
|
||||
mmioClose(hmmioIn, 0);
|
||||
hmmioIn = NULL;
|
||||
}
|
||||
|
||||
return(nError);
|
||||
|
||||
}
|
||||
|
||||
/* This routine saves a wave file in currently in memory.
|
||||
pszFileName - FileName to save to. Automatically overwritten, be careful!
|
||||
cbSize - Size in bytes to write.
|
||||
cSamples - # of samples to write, used to make the fact chunk. (if !PCM)
|
||||
pwfxDest - Pointer to waveformatex structure.
|
||||
pbData - Pointer to the data.
|
||||
*/
|
||||
|
||||
int WaveSaveFile(
|
||||
TCHAR*pszFileName, // (IN)
|
||||
UINT cbSize, // (IN)
|
||||
DWORD cSamples, // (IN)
|
||||
WAVEFORMATEX *pwfxDest, // (IN)
|
||||
BYTE *pbData // (IN)
|
||||
)
|
||||
{
|
||||
|
||||
HMMIO hmmioOut;
|
||||
MMCKINFO ckOut;
|
||||
MMCKINFO ckOutRIFF;
|
||||
MMIOINFO mmioinfoOut;
|
||||
UINT cbActualWrite;
|
||||
int nError;
|
||||
|
||||
if ((nError = WaveCreateFile(pszFileName, &hmmioOut, pwfxDest, &ckOut, &ckOutRIFF)) != 0)
|
||||
{
|
||||
goto ERROR_SAVING;
|
||||
}
|
||||
|
||||
if ((nError = WaveStartDataWrite(&hmmioOut, &ckOut, &mmioinfoOut)) != 0)
|
||||
{
|
||||
goto ERROR_SAVING;
|
||||
}
|
||||
|
||||
if ((nError = WaveWriteFile(hmmioOut, cbSize, pbData, &ckOut, &cbActualWrite, &mmioinfoOut)) != 0)
|
||||
{
|
||||
goto ERROR_SAVING;
|
||||
}
|
||||
|
||||
if ((nError = WaveCloseWriteFile(&hmmioOut, &ckOut, &ckOutRIFF, &mmioinfoOut, cSamples)) != 0)
|
||||
{
|
||||
goto ERROR_SAVING;
|
||||
}
|
||||
|
||||
ERROR_SAVING:
|
||||
|
||||
return(nError);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Wave.h
|
||||
//
|
||||
// Desc: DirectShow sample code - wave header file.
|
||||
//
|
||||
// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __WAVE_INCLUDED__
|
||||
#define __WAVE_INCLUDED__
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WAVEVERSION 1
|
||||
|
||||
#ifndef ER_MEM
|
||||
#define ER_MEM 0xe000
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTOPEN
|
||||
#define ER_CANNOTOPEN 0xe100
|
||||
#endif
|
||||
|
||||
#ifndef ER_NOTWAVEFILE
|
||||
#define ER_NOTWAVEFILE 0xe101
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTREAD
|
||||
#define ER_CANNOTREAD 0xe102
|
||||
#endif
|
||||
|
||||
#ifndef ER_CORRUPTWAVEFILE
|
||||
#define ER_CORRUPTWAVEFILE 0xe103
|
||||
#endif
|
||||
|
||||
#ifndef ER_CANNOTWRITE
|
||||
#define ER_CANNOTWRITE 0xe104
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int WaveOpenFile(TCHAR*, HMMIO *, WAVEFORMATEX **, MMCKINFO *);
|
||||
int WaveStartDataRead(HMMIO *, MMCKINFO *, MMCKINFO *);
|
||||
int WaveReadFile(HMMIO, UINT, BYTE *, MMCKINFO *, UINT *);
|
||||
int WaveCloseReadFile(HMMIO *, WAVEFORMATEX **);
|
||||
|
||||
int WaveCreateFile(TCHAR*, HMMIO *, WAVEFORMATEX *, MMCKINFO *, MMCKINFO *);
|
||||
int WaveStartDataWrite(HMMIO *, MMCKINFO *, MMIOINFO *);
|
||||
int WaveWriteFile(HMMIO, UINT, BYTE *, MMCKINFO *, UINT *, MMIOINFO *);
|
||||
int WaveCloseWriteFile(HMMIO *, MMCKINFO *, MMCKINFO *, MMIOINFO *, DWORD);
|
||||
|
||||
int WaveLoadFile(TCHAR*, UINT *, WAVEFORMATEX **, BYTE **);
|
||||
int WaveSaveFile(TCHAR*, UINT, DWORD, WAVEFORMATEX *, BYTE *);
|
||||
|
||||
int WaveCopyUselessChunks(HMMIO *, MMCKINFO *, MMCKINFO *, HMMIO *, MMCKINFO *, MMCKINFO *);
|
||||
BOOL riffCopyChunk(HMMIO, HMMIO, const LPMMCKINFO);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Sample.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definition of CSample class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __SAMPLE_H_
|
||||
#define __SAMPLE_H_
|
||||
|
||||
|
||||
// df20ddfa-0d19-463a-ab46-e5d8ef6efd69
|
||||
DEFINE_GUID(CLSID_Sample,
|
||||
0xdf20ddfa, 0x0d19, 0x463a, 0xab, 0x46, 0xe5, 0xd8, 0xef, 0x6e, 0xfd, 0x69);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSample
|
||||
class ATL_NO_VTABLE CSample :
|
||||
public IMediaObjectImpl<CSample, 1, 2>, // 1 input, 2 outputs
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public CComCoClass<CSample, &CLSID_Sample>
|
||||
|
||||
{
|
||||
public:
|
||||
CSample()
|
||||
{
|
||||
m_pUnkMarshaler = NULL;
|
||||
}
|
||||
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_SAMPLE)
|
||||
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CSample)
|
||||
COM_INTERFACE_ENTRY(IMediaObject)
|
||||
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
|
||||
END_COM_MAP()
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return CoCreateFreeThreadedMarshaler(
|
||||
GetControllingUnknown(), &m_pUnkMarshaler.p);
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
// Make sure we clean up
|
||||
FreeStreamingResources();
|
||||
m_pUnkMarshaler.Release();
|
||||
}
|
||||
|
||||
// IMediaObjectImpl callbacks
|
||||
HRESULT InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags);
|
||||
HRESULT InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags);
|
||||
HRESULT InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt);
|
||||
HRESULT InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbMaxLookahead, DWORD *pcbAlignment);
|
||||
HRESULT InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbAlignment);
|
||||
HRESULT InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency);
|
||||
HRESULT InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency);
|
||||
HRESULT InternalFlush();
|
||||
HRESULT InternalDiscontinuity(DWORD dwInputStreamIndex);
|
||||
HRESULT InternalAllocateStreamingResources();
|
||||
HRESULT InternalFreeStreamingResources();
|
||||
HRESULT InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
|
||||
DWORD dwFlags, REFERENCE_TIME rtTimestamp,
|
||||
REFERENCE_TIME rtTimelength);
|
||||
HRESULT InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount,
|
||||
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
|
||||
DWORD *pdwStatus);
|
||||
HRESULT InternalAcceptingInput(DWORD dwInputStreamIndex);
|
||||
|
||||
|
||||
// Internal processing routine
|
||||
HRESULT Process();
|
||||
|
||||
CComPtr<IUnknown> m_pUnkMarshaler;
|
||||
|
||||
// Streaming locals
|
||||
CComPtr<IMediaBuffer> m_pBuffer;
|
||||
BYTE * m_pbData;
|
||||
DWORD m_cbData;
|
||||
|
||||
// Fabricate timestamps based on the average time per from if there isn't one in the stream
|
||||
REFERENCE_TIME m_rtFrame;
|
||||
|
||||
// Current state info
|
||||
CStreamState m_StreamState;
|
||||
bool m_bPicture;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
#endif //__SAMPLE_H_
|
||||
@@ -0,0 +1,14 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {df20ddfa-0d19-463a-ab46-e5d8ef6efd69} = s ' DMO Sample Class'
|
||||
{
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Both'
|
||||
}
|
||||
val MERIT = d '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// stdafx.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _ATL_STATIC_REGISTRY
|
||||
#include <statreg.h>
|
||||
#include <statreg.cpp>
|
||||
#endif
|
||||
|
||||
#include <atlimpl.cpp>
|
||||
@@ -0,0 +1,34 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED_)
|
||||
#define AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define STRICT
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#define _ATL_FREE_THREADED
|
||||
|
||||
#define _ATL_STATIC_REGISTRY
|
||||
|
||||
#pragma warning(disable:4701) // Disable C4701
|
||||
|
||||
#include <atlbase.h>
|
||||
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
extern CComModule _Module;
|
||||
|
||||
#include <atlcom.h>
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__9C2D1EC0_3838_4746_AD1D_EB6E217364A3__INCLUDED)
|
||||
@@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: DMOSample.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of DLL exports.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#define FIX_LOCK_NAME
|
||||
#include <dmo.h>
|
||||
|
||||
#include <dmoimpl.h>
|
||||
#include "resource.h"
|
||||
#include <initguid.h>
|
||||
#include <limits.h>
|
||||
#include "state.h"
|
||||
#include "Sample.h"
|
||||
|
||||
|
||||
CComModule _Module;
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_Sample, CSample)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Point
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
_Module.Init(ObjectMap, hInstance);
|
||||
DisableThreadLibraryCalls(hInstance);
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH)
|
||||
_Module.Term();
|
||||
return TRUE; // ok
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Returns a class factory to create an object of the requested type
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
return _Module.GetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllRegisterServer - Adds entries to the system registry
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
// Register ourselves as a DMO with no types
|
||||
// RGS file also registers with a merit of 0 so DShow won't try to use us
|
||||
DMORegister(L"DMO Sample",
|
||||
CLSID_Sample,
|
||||
DMOCATEGORY_VIDEO_DECODER,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
// registers object
|
||||
return _Module.RegisterServer();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllUnregisterServer - Removes entries from the system registry
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
DMOUnregister(CLSID_Sample, DMOCATEGORY_VIDEO_DECODER);
|
||||
return _Module.UnregisterServer();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
; dmosample.def : Declares the module parameters.
|
||||
|
||||
LIBRARY "dmosample.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <activex.ver>
|
||||
#include "resource.h"
|
||||
|
||||
#include "winres.h"
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REGISTRY
|
||||
//
|
||||
//==========================================================================;
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
||||
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
||||
// PURPOSE.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All Rights Reserved.
|
||||
//
|
||||
//--------------------------------------------------------------------------;
|
||||
|
||||
IDR_SAMPLE REGISTRY DISCARDABLE "Sample.rgs"
|
||||
|
||||
|
||||
//
|
||||
// Version Info
|
||||
//
|
||||
#define VERSION_RES_BIN_NAME "DMOSample.dll\0"
|
||||
#define VERSION_RES_BIN_DESCRIPTION "DMO Sample Filter (Sample)\0"
|
||||
|
||||
#define AMOVIE_SELF_REGISTER
|
||||
|
||||
#include <activex.rcv>
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
DirectShow Sample -- DMOSample
|
||||
------------------------------
|
||||
|
||||
DMO Sample is a sample Microsoft DirectX Media Object (DMO). It takes MPEG-1
|
||||
video packets as input and produces two output streams. The first output stream
|
||||
contains video frames in RGB 565 format. Each frame displays the time code
|
||||
taken from the MPEG-1 video, and is otherwise blank. The second output stream
|
||||
is an optional text stream with the time code.
|
||||
|
||||
DMO Sample uses the IMediaObjectImpl base-class template to implement the
|
||||
IMediaObject interface. For information about using this template, see
|
||||
"Using the DMO Base Class" in the DirectX 8 SDK documentation.
|
||||
The Active Template Library (ATL) handles various COM details, including
|
||||
registration, aggregation, IUnknown, and the DLL entry points.
|
||||
|
||||
|
||||
For more information about this sample, see "DirectShow Samples" in the
|
||||
DirectX 8 SDK documentation.
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
#define IDR_SAMPLE 101
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Sample.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CSample class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#define FIX_LOCK_NAME
|
||||
#include <dmo.h>
|
||||
|
||||
#include <limits.h> // _I64_MAX
|
||||
#include <crtdbg.h>
|
||||
#include <dmoimpl.h>
|
||||
#include <uuids.h> // DirectShow media type guids
|
||||
#include <amvideo.h> // VIDEOINFOHEADER definition
|
||||
#include "resource.h"
|
||||
#include "state.h"
|
||||
#include "Sample.h"
|
||||
#include "util.h" // Helpers
|
||||
|
||||
#pragma warning(disable:4100) // Disable C4100: unreferenced formal parameter
|
||||
|
||||
|
||||
HRESULT CSample::InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags)
|
||||
{
|
||||
// We can process data on any boundary
|
||||
*pdwFlags = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CSample::InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags)
|
||||
{
|
||||
// We output single frames
|
||||
if (0 == dwOutputStreamIndex) {
|
||||
*pdwFlags = DMO_OUTPUT_STREAMF_WHOLE_SAMPLES |
|
||||
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
|
||||
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE;
|
||||
} else {
|
||||
// Stream 1
|
||||
// Just text, no special buffering but 1 sample per sample
|
||||
*pdwFlags = DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER |
|
||||
DMO_OUTPUT_STREAMF_OPTIONAL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CSample::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
|
||||
{
|
||||
// Check if the type is already set and if so reject any type that's not identical
|
||||
if (InputTypeSet(dwInputStreamIndex)) {
|
||||
if (!TypesMatch(pmt, InputType(dwInputStreamIndex))) {
|
||||
return DMO_E_INVALIDTYPE;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// We accept MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Video
|
||||
// Check the format is defined
|
||||
if (pmt->majortype == MEDIATYPE_Video &&
|
||||
pmt->subtype == MEDIASUBTYPE_MPEG1Payload &&
|
||||
pmt->formattype == FORMAT_MPEGVideo &&
|
||||
pmt->pbFormat != NULL) {
|
||||
return S_OK;
|
||||
} else {
|
||||
return DMO_E_INVALIDTYPE;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CSample::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
|
||||
{
|
||||
// Check if the type is already set and if so reject any type that's not identical
|
||||
if (OutputTypeSet(dwOutputStreamIndex)) {
|
||||
if (!TypesMatch(pmt, OutputType(dwOutputStreamIndex))) {
|
||||
return DMO_E_INVALIDTYPE;
|
||||
} else {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
// We output frames on stream 1
|
||||
if (dwOutputStreamIndex == 0) {
|
||||
if (!InputTypeSet(0)) {
|
||||
return DMO_E_INVALIDTYPE;
|
||||
}
|
||||
if (pmt->majortype == MEDIATYPE_Video &&
|
||||
pmt->subtype == MEDIASUBTYPE_RGB565 &&
|
||||
pmt->formattype == FORMAT_VideoInfo &&
|
||||
pmt->pbFormat != NULL) {
|
||||
const VIDEOINFOHEADER *pvihInput = (const VIDEOINFOHEADER *)InputType(0)->pbFormat;
|
||||
const VIDEOINFOHEADER *pvihOutput = (const VIDEOINFOHEADER *)pmt->pbFormat;
|
||||
|
||||
LONG lWidth, lHeight;
|
||||
if (IsRectEmpty(&pvihOutput->rcTarget)) {
|
||||
lWidth = pvihOutput->bmiHeader.biWidth;
|
||||
lHeight = pvihOutput->bmiHeader.biHeight;
|
||||
} else {
|
||||
lWidth = pvihOutput->rcTarget.right - pvihOutput->rcTarget.left;
|
||||
lHeight = pvihOutput->rcTarget.bottom - pvihOutput->rcTarget.top;
|
||||
}
|
||||
if (pvihInput->bmiHeader.biWidth == lWidth &&
|
||||
pvihInput->bmiHeader.biHeight == lHeight) {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return DMO_E_INVALIDTYPE;
|
||||
} else {
|
||||
// Stream 1
|
||||
if (pmt->majortype == MEDIATYPE_Text && pmt->subtype == GUID_NULL) {
|
||||
return S_OK;
|
||||
} else {
|
||||
return DMO_E_INVALIDTYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT CSample::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt)
|
||||
{
|
||||
// No types to all indices for dwTypeIndex are out of range.
|
||||
return DMO_E_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
HRESULT CSample::InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
|
||||
DMO_MEDIA_TYPE *pmt)
|
||||
{
|
||||
if (!InputTypeSet(0)) {
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
}
|
||||
|
||||
if (dwTypeIndex != 0) {
|
||||
return DMO_E_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
// If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
|
||||
// Return DMO_E_NO_MORE_ITEMS if the type does not exists. See the
|
||||
// documentation for IMediaObject::GetOutputType() for more information.
|
||||
if (NULL != pmt) {
|
||||
if (dwOutputStreamIndex == 0) {
|
||||
|
||||
// Create our media type
|
||||
HRESULT hr = MoInitMediaType(pmt, FIELD_OFFSET(VIDEOINFO, dwBitMasks[3]));
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
const VIDEOINFOHEADER *pvihInput = (const VIDEOINFOHEADER *)InputType(0)->pbFormat;
|
||||
LONG lWidth = pvihInput->bmiHeader.biWidth;
|
||||
LONG lHeight = pvihInput->bmiHeader.biHeight;
|
||||
|
||||
// Initialize the media type structure (MoInitMediaType initalized cbFormat
|
||||
// and pbFormat)
|
||||
pmt->majortype = MEDIATYPE_Video;
|
||||
pmt->subtype = MEDIASUBTYPE_RGB565;
|
||||
pmt->bFixedSizeSamples = TRUE;
|
||||
pmt->bTemporalCompression = FALSE;
|
||||
pmt->lSampleSize = lWidth * lHeight * 2;
|
||||
pmt->formattype = FORMAT_VideoInfo;
|
||||
pmt->pUnk = NULL;
|
||||
|
||||
// Initialize the format
|
||||
VIDEOINFO *pviOutput = (VIDEOINFO *)pmt->pbFormat;
|
||||
ZeroMemory(pviOutput, FIELD_OFFSET(VIDEOINFO, dwBitMasks[3]));
|
||||
pviOutput->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
pviOutput->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
pviOutput->bmiHeader.biBitCount = 16;
|
||||
pviOutput->bmiHeader.biPlanes = 1;
|
||||
pviOutput->bmiHeader.biWidth = lWidth;
|
||||
pviOutput->bmiHeader.biHeight = lHeight;
|
||||
pviOutput->bmiHeader.biSizeImage = pmt->lSampleSize;
|
||||
pviOutput->TrueColorInfo.dwBitMasks[0] = 0xF800;
|
||||
pviOutput->TrueColorInfo.dwBitMasks[1] = 0x07E0;
|
||||
pviOutput->TrueColorInfo.dwBitMasks[2] = 0x001F;
|
||||
pviOutput->AvgTimePerFrame = pvihInput->AvgTimePerFrame;
|
||||
} else {
|
||||
ZeroMemory(pmt, sizeof(*pmt));
|
||||
pmt->majortype = MEDIATYPE_Text;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbMaxLookahead, DWORD *pcbAlignment)
|
||||
{
|
||||
*pcbSize = 1;
|
||||
*pcbMaxLookahead = 0;
|
||||
*pcbAlignment = 1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
|
||||
DWORD *pcbAlignment)
|
||||
{
|
||||
*pcbAlignment = 1;
|
||||
if (dwOutputStreamIndex == 0) {
|
||||
*pcbSize = OutputType(0)->lSampleSize;
|
||||
return S_OK;
|
||||
} else {
|
||||
*pcbSize = sizeof(L"hh:mm:ss:ff"); // hh:mm:ss:ff
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
HRESULT CSample::InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT CSample::InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
HRESULT CSample::InternalFlush()
|
||||
{
|
||||
InternalDiscontinuity(0);
|
||||
|
||||
// Release buffer
|
||||
m_pBuffer = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalDiscontinuity(DWORD dwInputStreamIndex)
|
||||
{
|
||||
// Zero our timestamp
|
||||
m_rtFrame = 0;
|
||||
|
||||
// No pictures yet
|
||||
m_bPicture = false;
|
||||
|
||||
// Reset state machine
|
||||
m_StreamState.Reset();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalAllocateStreamingResources()
|
||||
{
|
||||
// Reinitialize variables
|
||||
InternalDiscontinuity(0);
|
||||
|
||||
// Allocate our bitmap
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalFreeStreamingResources()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
|
||||
DWORD dwFlags, REFERENCE_TIME rtTimestamp,
|
||||
REFERENCE_TIME rtTimelength)
|
||||
{
|
||||
// Check parameters
|
||||
_ASSERTE(m_pBuffer == NULL);
|
||||
HRESULT hr = pBuffer->GetBufferAndLength(&m_pbData, &m_cbData);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
m_pBuffer = pBuffer;
|
||||
|
||||
if (0 == (dwFlags & DMO_INPUT_DATA_BUFFERF_TIME)) {
|
||||
rtTimestamp = INVALID_TIME;
|
||||
}
|
||||
|
||||
m_StreamState.TimeStamp(rtTimestamp);
|
||||
|
||||
// Process() returns S_FALSE if there is no output, S_OK otherwise
|
||||
hr = Process();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSample::InternalProcessOutput(DWORD dwFlags,
|
||||
DWORD cOutputBufferCount,
|
||||
DMO_OUTPUT_DATA_BUFFER *pOutputBuffers,
|
||||
DWORD *pdwStatus)
|
||||
{
|
||||
// Check buffer
|
||||
PBYTE pbData;
|
||||
DWORD cbData;
|
||||
DWORD cbCurrent;
|
||||
|
||||
// Do we have any output?
|
||||
if (!m_bPicture) {
|
||||
return S_FALSE;
|
||||
}
|
||||
HRESULT hr = pOutputBuffers[0].pBuffer->GetBufferAndLength(
|
||||
&pbData, &cbCurrent);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
hr = pOutputBuffers[0].pBuffer->GetMaxLength(&cbData);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (cbData < cbCurrent + (DWORD)OutputType(0)->lSampleSize) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Say we've filled the buffer
|
||||
hr = pOutputBuffers[0].pBuffer->SetLength(cbCurrent + (DWORD)OutputType(0)->lSampleSize);
|
||||
|
||||
cbData -= cbCurrent;
|
||||
pbData += cbCurrent;
|
||||
|
||||
// Generate our data
|
||||
DWORD dwTimeCode;
|
||||
REFERENCE_TIME rt = m_StreamState.PictureTime(&dwTimeCode);
|
||||
TCHAR szBuffer[20];
|
||||
wsprintf(szBuffer, TEXT("%2.2d:%2.2d:%2.2d:%2.2d"),
|
||||
(dwTimeCode >> 19) & 0x1F,
|
||||
(dwTimeCode >> 13) & 0x3F,
|
||||
(dwTimeCode >> 6) & 0x3F,
|
||||
dwTimeCode & 0x3F);
|
||||
|
||||
// Update our bitmap with turquoise
|
||||
OurFillRect((const VIDEOINFOHEADER *)OutputType(0)->pbFormat, pbData, 0x03EF);
|
||||
|
||||
// Draw our text
|
||||
DrawOurText((const VIDEOINFOHEADER *)OutputType(0)->pbFormat, pbData, szBuffer);
|
||||
|
||||
pOutputBuffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT;
|
||||
|
||||
// Set the timestamp
|
||||
if (rt != INVALID_TIME) {
|
||||
pOutputBuffers[0].rtTimestamp = rt;
|
||||
|
||||
} else {
|
||||
pOutputBuffers[0].rtTimestamp = m_rtFrame;
|
||||
}
|
||||
REFERENCE_TIME rtLength = ((const VIDEOINFOHEADER *)OutputType(0)->pbFormat)->AvgTimePerFrame;
|
||||
pOutputBuffers[0].rtTimelength = rtLength;
|
||||
m_rtFrame = pOutputBuffers[0].rtTimestamp + rtLength;
|
||||
|
||||
// Uncompressed video must always have a timestamp
|
||||
pOutputBuffers[0].dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIME | DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH;
|
||||
|
||||
// Update our state
|
||||
m_bPicture = false;
|
||||
|
||||
// Is there any more data to output at this point?
|
||||
if (S_OK == Process()) {
|
||||
pOutputBuffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
|
||||
}
|
||||
|
||||
// Is there an output buffer for stream 1?
|
||||
if (pOutputBuffers[1].pBuffer) {
|
||||
PBYTE pbData;
|
||||
DWORD cbLength;
|
||||
DWORD cbMax;
|
||||
DWORD dwLen = lstrlen(szBuffer) * sizeof(WCHAR);
|
||||
if (S_OK == pOutputBuffers[1].pBuffer->GetBufferAndLength(&pbData, &cbLength) &&
|
||||
S_OK == pOutputBuffers[1].pBuffer->GetMaxLength(&cbMax) &&
|
||||
cbLength + dwLen <= cbMax) {
|
||||
|
||||
// Convert to UNICODE!
|
||||
USES_CONVERSION;
|
||||
LPWSTR lpsz = T2W(szBuffer);
|
||||
|
||||
CopyMemory(pbData + cbLength, lpsz, dwLen);
|
||||
pOutputBuffers[1].pBuffer->SetLength(cbLength + dwLen);
|
||||
pOutputBuffers[1].dwStatus = pOutputBuffers[0].dwStatus;
|
||||
pOutputBuffers[1].rtTimestamp = pOutputBuffers[0].rtTimestamp;
|
||||
pOutputBuffers[1].rtTimelength = rtLength;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CSample::InternalAcceptingInput(DWORD dwInputStreamIndex)
|
||||
{
|
||||
return m_pBuffer == NULL ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
// Scan input data until either we're exhausted or we find
|
||||
// a picture start code
|
||||
// Note GOP time codes as we encounter them so we can
|
||||
// output time codes
|
||||
|
||||
HRESULT CSample::Process()
|
||||
{
|
||||
// Process bytes and update our state machine
|
||||
while (m_cbData && !m_bPicture) {
|
||||
m_bPicture = m_StreamState.NextByte(*m_pbData);
|
||||
m_cbData--;
|
||||
m_pbData++;
|
||||
}
|
||||
|
||||
// Release buffer if we're done with it
|
||||
if (m_cbData == 0) {
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
|
||||
// assert that if have no picture to output then we ate all the data
|
||||
_ASSERTE(m_bPicture || m_cbData == 0);
|
||||
return m_bPicture ? S_OK : S_FALSE;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
# Microsoft Developer Studio Project File - Name="dmosample" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=dmosample - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "sample.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "sample.mak" CFG="dmosample - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "dmosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "dmosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "dmosample - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /i "..\..\BaseClasses" /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /map /machine:I386 /def:"dmosample.def" /out:"Release\dmosample.dll" /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "dmosample - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /i "..\..\BaseClasses" /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /debug /machine:I386 /def:"dmosample.def" /out:"Debug\dmosample.dll" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "dmosample - Win32 Release"
|
||||
# Name "dmosample - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dmosample.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sample.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\state.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Sample.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\State.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dmosample.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Sample.rgs
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "sample"=.\sample.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Based on sample.dsp
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=dmosample - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to dmosample - Win32 Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "dmosample - Win32 Release" && "$(CFG)" != "dmosample - Win32 Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "sample.mak" CFG="dmosample - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "dmosample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "dmosample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "dmosample - Win32 Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\dmosample.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\dmosample.obj"
|
||||
-@erase "$(INTDIR)\dmosample.res"
|
||||
-@erase "$(INTDIR)\sample.obj"
|
||||
-@erase "$(INTDIR)\state.obj"
|
||||
-@erase "$(INTDIR)\StdAfx.obj"
|
||||
-@erase "$(INTDIR)\util.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\dmosample.dll"
|
||||
-@erase "$(OUTDIR)\dmosample.exp"
|
||||
-@erase "$(OUTDIR)\dmosample.lib"
|
||||
-@erase "$(OUTDIR)\dmosample.map"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /Fp"$(INTDIR)\sample.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmosample.res" /i "..\..\BaseClasses" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\dmosample.pdb" /map:"$(INTDIR)\dmosample.map" /machine:I386 /def:"dmosample.def" /out:"$(OUTDIR)\dmosample.dll" /implib:"$(OUTDIR)\dmosample.lib" /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\dmosample.obj" \
|
||||
"$(INTDIR)\sample.obj" \
|
||||
"$(INTDIR)\state.obj" \
|
||||
"$(INTDIR)\StdAfx.obj" \
|
||||
"$(INTDIR)\util.obj" \
|
||||
"$(INTDIR)\dmosample.res"
|
||||
|
||||
"$(OUTDIR)\dmosample.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "dmosample - Win32 Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\dmosample.dll"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\dmosample.obj"
|
||||
-@erase "$(INTDIR)\dmosample.res"
|
||||
-@erase "$(INTDIR)\sample.obj"
|
||||
-@erase "$(INTDIR)\state.obj"
|
||||
-@erase "$(INTDIR)\StdAfx.obj"
|
||||
-@erase "$(INTDIR)\util.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\dmosample.dll"
|
||||
-@erase "$(OUTDIR)\dmosample.exp"
|
||||
-@erase "$(OUTDIR)\dmosample.ilk"
|
||||
-@erase "$(OUTDIR)\dmosample.lib"
|
||||
-@erase "$(OUTDIR)\dmosample.pdb"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DMOSAMPLE_EXPORTS" /Fp"$(INTDIR)\sample.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dmosample.res" /i "..\..\BaseClasses" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\sample.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\dmosample.pdb" /debug /machine:I386 /def:"dmosample.def" /out:"$(OUTDIR)\dmosample.dll" /implib:"$(OUTDIR)\dmosample.lib" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\dmosample.obj" \
|
||||
"$(INTDIR)\sample.obj" \
|
||||
"$(INTDIR)\state.obj" \
|
||||
"$(INTDIR)\StdAfx.obj" \
|
||||
"$(INTDIR)\util.obj" \
|
||||
"$(INTDIR)\dmosample.res"
|
||||
|
||||
"$(OUTDIR)\dmosample.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1"
|
||||
!IF EXISTS("sample.dep")
|
||||
!INCLUDE "sample.dep"
|
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "sample.dep"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "dmosample - Win32 Release" || "$(CFG)" == "dmosample - Win32 Debug"
|
||||
SOURCE=.\dmosample.cpp
|
||||
|
||||
"$(INTDIR)\dmosample.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\sample.cpp
|
||||
|
||||
"$(INTDIR)\sample.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\state.cpp
|
||||
|
||||
"$(INTDIR)\state.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
|
||||
"$(INTDIR)\StdAfx.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\util.cpp
|
||||
|
||||
"$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
SOURCE=.\dmosample.rc
|
||||
|
||||
"$(INTDIR)\dmosample.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) $(RSC_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: State.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CStreamState class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <limits.h> // _I64_MAX
|
||||
#include <crtdbg.h>
|
||||
#include <dmo.h>
|
||||
#include "state.h"
|
||||
|
||||
void CStreamState::TimeStamp(REFERENCE_TIME rt)
|
||||
{
|
||||
DWORD dwIndex = m_cbBytes >= 4 ? 0 : m_cbBytes;
|
||||
m_arTS[dwIndex].bValid = true;
|
||||
m_arTS[dwIndex].rt = rt;
|
||||
}
|
||||
|
||||
void CStreamState::Reset()
|
||||
{
|
||||
m_cbBytes = 0;
|
||||
m_dwNextTimeCode = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
m_arTS[i].bValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CStreamState::NextByte(BYTE bData)
|
||||
{
|
||||
_ASSERTE(m_arTS[0].bValid);
|
||||
switch (m_cbBytes) {
|
||||
case 0:
|
||||
if (bData == 0) {
|
||||
m_cbBytes++;
|
||||
}
|
||||
return false;
|
||||
case 1:
|
||||
if (bData == 0) {
|
||||
m_cbBytes++;
|
||||
} else {
|
||||
m_cbBytes = 0;
|
||||
|
||||
// Pick up new timestamp if there was one
|
||||
if (m_arTS[1].bValid) {
|
||||
m_arTS[0].rt = m_arTS[1].rt;
|
||||
m_arTS[1].bValid = false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case 2:
|
||||
if (bData == 1) {
|
||||
m_cbBytes++;
|
||||
} else {
|
||||
if (bData == 0) {
|
||||
if (m_arTS[1].bValid) {
|
||||
m_arTS[0].rt = m_arTS[1].rt;
|
||||
m_arTS[1].bValid = false;
|
||||
}
|
||||
if (m_arTS[2].bValid) {
|
||||
m_arTS[1] = m_arTS[2];
|
||||
m_arTS[2].bValid = false;
|
||||
}
|
||||
} else {
|
||||
// Not 0 or 1, revert
|
||||
m_cbBytes = 0;
|
||||
// and pick up latest timestamp
|
||||
if (m_arTS[1].bValid) {
|
||||
m_arTS[0].rt = m_arTS[1].rt;
|
||||
m_arTS[1].bValid = false;
|
||||
}
|
||||
if (m_arTS[2].bValid) {
|
||||
m_arTS[0].rt = m_arTS[2].rt;
|
||||
m_arTS[2].bValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case 3:
|
||||
{
|
||||
// It's a start code whatever it is
|
||||
// return the timestamp and reset everything
|
||||
m_rt = m_arTS[0].rt;
|
||||
|
||||
// If it's a picture start code can't use this timestamp again.
|
||||
if (0 == bData) {
|
||||
m_arTS[0].rt = INVALID_TIME;
|
||||
m_cbBytes = 0;
|
||||
}
|
||||
|
||||
// Catch up and clean out timestamps
|
||||
for (int i = 1; i < 4; i++) {
|
||||
if (m_arTS[i].bValid) {
|
||||
m_arTS[0].rt = m_arTS[i].rt;
|
||||
m_arTS[i].bValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Picture start code?
|
||||
if (0 == bData) {
|
||||
m_cbBytes = 0;
|
||||
m_dwTimeCode = m_dwNextTimeCode;
|
||||
m_dwNextTimeCode++;
|
||||
return true;
|
||||
} else {
|
||||
// Is it a GOP start code?
|
||||
if (bData == 0xb8) {
|
||||
m_cbBytes++;
|
||||
} else {
|
||||
m_cbBytes = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
m_bGOPData[m_cbBytes - 4] = bData;
|
||||
m_cbBytes++;
|
||||
if (m_cbBytes == 8) {
|
||||
m_cbBytes = 0;
|
||||
m_dwNextTimeCode = ((DWORD)m_bGOPData[0] << 17) +
|
||||
((DWORD)m_bGOPData[1] << 9) +
|
||||
((DWORD)m_bGOPData[2] << 1) +
|
||||
((DWORD)m_bGOPData[3] >> 7);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Should never reach here
|
||||
return false;
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: State.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definition of CStreamState class.
|
||||
// Provides state machine for picture start codes and timestamps.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// We need to know:
|
||||
//
|
||||
// - The time stamp to associate with a picture start code
|
||||
// - The next time stamp
|
||||
//
|
||||
// State:
|
||||
//
|
||||
// m_cbBytes - number of valid bytes of start code so far
|
||||
// m_arTS[4] - array of all the timestamps
|
||||
// m_cbBytes+1 entries are valid
|
||||
|
||||
|
||||
|
||||
// Not really invalid but unlikely enough for sample code.
|
||||
static const REFERENCE_TIME INVALID_TIME = _I64_MAX;
|
||||
|
||||
|
||||
class CStreamState
|
||||
{
|
||||
private:
|
||||
|
||||
DWORD m_cbBytes;
|
||||
struct {
|
||||
bool bValid;
|
||||
REFERENCE_TIME rt;
|
||||
} m_arTS[4];
|
||||
REFERENCE_TIME m_rt;
|
||||
BYTE m_bGOPData[4];
|
||||
DWORD m_dwTimeCode;
|
||||
DWORD m_dwNextTimeCode;
|
||||
|
||||
public:
|
||||
CStreamState()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
// Returns true if a start code was identifed
|
||||
bool NextByte(BYTE bData);
|
||||
void TimeStamp(REFERENCE_TIME rt);
|
||||
REFERENCE_TIME PictureTime(DWORD *pdwTimeCode) const
|
||||
{
|
||||
*pdwTimeCode = m_dwTimeCode;
|
||||
return m_rt;
|
||||
}
|
||||
void Reset();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Util.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of utility routines.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "dmo.h"
|
||||
#include "amvideo.h"
|
||||
#include "util.h"
|
||||
|
||||
// Helper to get the important info out of VIDEOINFOHEADER
|
||||
void GetVideoInfoParameters(
|
||||
const VIDEOINFOHEADER *pvih,
|
||||
PBYTE pbData,
|
||||
DWORD *pdwWidth,
|
||||
DWORD *pdwHeight,
|
||||
LONG *plStrideInBytes, // Add this on to a pointer to a row to get the new row down
|
||||
BYTE **ppbTop // Return position of first byte of top row of pixels
|
||||
)
|
||||
{
|
||||
LONG lStride;
|
||||
|
||||
// biWidth is the stride in pixels for 'normal formats'
|
||||
// Expand to bytes and round up to a multiple of 4
|
||||
if (pvih->bmiHeader.biBitCount != 0 &&
|
||||
0 == (7 & pvih->bmiHeader.biBitCount)) {
|
||||
lStride = (pvih->bmiHeader.biWidth * (pvih->bmiHeader.biBitCount / 8) + 3) & ~3;
|
||||
} else {
|
||||
lStride = pvih->bmiHeader.biWidth;
|
||||
}
|
||||
|
||||
// If rcTarget is empty it means 'the whole image'
|
||||
if (IsRectEmpty(&pvih->rcTarget)) {
|
||||
*pdwWidth = (DWORD)pvih->bmiHeader.biWidth;
|
||||
*pdwHeight = (DWORD)(abs(pvih->bmiHeader.biHeight));
|
||||
if (pvih->bmiHeader.biHeight < 0) {
|
||||
*plStrideInBytes = lStride;
|
||||
*ppbTop = pbData;
|
||||
} else {
|
||||
*plStrideInBytes = -lStride;
|
||||
*ppbTop = pbData + lStride * (*pdwHeight - 1);
|
||||
}
|
||||
} else {
|
||||
*pdwWidth = (DWORD)(pvih->rcTarget.right - pvih->rcTarget.left);
|
||||
*pdwHeight = (DWORD)(pvih->rcTarget.bottom - pvih->rcTarget.top);
|
||||
if (pvih->bmiHeader.biHeight < 0) {
|
||||
*plStrideInBytes = lStride;
|
||||
*ppbTop = pbData +
|
||||
lStride * pvih->rcTarget.top +
|
||||
(pvih->bmiHeader.biBitCount * pvih->rcTarget.left) / 8;
|
||||
} else {
|
||||
*plStrideInBytes = -lStride;
|
||||
*ppbTop = pbData +
|
||||
lStride * (pvih->bmiHeader.biHeight - pvih->rcTarget.top - 1) +
|
||||
(pvih->bmiHeader.biBitCount * pvih->rcTarget.left) / 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stuff to draw string
|
||||
PBYTE TextBitmap(LPCTSTR lpsz, SIZE *pSize)
|
||||
{
|
||||
HDC hdc = CreateCompatibleDC(NULL);
|
||||
if (NULL == hdc) {
|
||||
return NULL;
|
||||
}
|
||||
if (!GetTextExtentPoint32(hdc, lpsz, lstrlen(lpsz), pSize))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create our bitmap
|
||||
struct {
|
||||
BITMAPINFOHEADER bmiHeader;
|
||||
DWORD rgbEntries[2];
|
||||
} bmi =
|
||||
{
|
||||
{
|
||||
sizeof(BITMAPINFOHEADER),
|
||||
pSize->cx,
|
||||
pSize->cy,
|
||||
1,
|
||||
1,
|
||||
BI_RGB,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
},
|
||||
{
|
||||
0x00000000,
|
||||
0xFFFFFFFF
|
||||
}
|
||||
};
|
||||
|
||||
HBITMAP hbm = CreateDIBitmap(hdc, &bmi.bmiHeader, 0, NULL, NULL, 0);
|
||||
if (NULL == hbm) {
|
||||
DeleteDC(hdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HGDIOBJ hobj = SelectObject(hdc, hbm);
|
||||
if (NULL == hobj) {
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(hdc);
|
||||
return NULL;
|
||||
}
|
||||
PBYTE pbReturn = NULL;
|
||||
BOOL bResult = ExtTextOut(hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, NULL, lpsz,
|
||||
lstrlen(lpsz), NULL);
|
||||
SelectObject(hdc, hobj);
|
||||
LONG lLines;
|
||||
if (bResult) {
|
||||
LONG lWidthInBytes = ((pSize->cx + 31) >> 3) & ~3;
|
||||
pbReturn = new BYTE[lWidthInBytes * pSize->cy];
|
||||
if (pbReturn) {
|
||||
ZeroMemory(pbReturn, lWidthInBytes * pSize->cy);
|
||||
lLines = GetDIBits(hdc, hbm, 0, pSize->cy, (PVOID)pbReturn, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
|
||||
}
|
||||
}
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(hdc);
|
||||
return pbReturn;
|
||||
}
|
||||
|
||||
// Helper to fill memory
|
||||
void OurFillRect(const VIDEOINFOHEADER *pvih, PBYTE pbData, WORD wVal)
|
||||
{
|
||||
DWORD dwWidth, dwHeight;
|
||||
LONG lStrideInBytes;
|
||||
PBYTE pbTop;
|
||||
GetVideoInfoParameters(pvih, pbData, &dwWidth, &dwHeight, &lStrideInBytes, &pbTop);
|
||||
|
||||
PBYTE pbPixels = pbTop;
|
||||
|
||||
// For just filling we don't care which way up the bitmap is - we just start at pbData
|
||||
for (DWORD dwCount = 0; dwCount < dwHeight; dwCount++) {
|
||||
WORD *pWord = (WORD *)pbPixels;
|
||||
for (DWORD dwPixel = 0; dwPixel < dwWidth; dwPixel++) {
|
||||
pWord[dwPixel] = wVal;
|
||||
}
|
||||
// biWidth is the stride
|
||||
pbPixels += lStrideInBytes;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to get some text into memory (note we're ignoring errors!)
|
||||
void DrawOurText(const VIDEOINFOHEADER * pvih, PBYTE pbData, LPCTSTR szBuffer)
|
||||
{
|
||||
|
||||
// Copy the data into our real buffer (top lhs)
|
||||
DWORD dwWidthTarget, dwHeightTarget;
|
||||
LONG lStrideInBytesTarget;
|
||||
PBYTE pbTarget;
|
||||
|
||||
SIZE size;
|
||||
|
||||
// Get a bit map representing our bits
|
||||
PBYTE pbBits = TextBitmap(szBuffer, &size);
|
||||
if (NULL == pbBits) {
|
||||
return;
|
||||
}
|
||||
GetVideoInfoParameters(pvih, pbData, &dwWidthTarget, &dwHeightTarget, &lStrideInBytesTarget, &pbTarget);
|
||||
|
||||
// Now copy the data from the DIB section (which is bottom up)
|
||||
// but first check if it's too big
|
||||
if (dwWidthTarget >= (DWORD)size.cx && dwHeightTarget > (DWORD)size.cy && size.cx > 0 && size.cy > 0) {
|
||||
// PBYTE pbSource = (PBYTE)pbBits;
|
||||
DWORD dwSourceStride = ((size.cx + 31) >> 3) & ~3;
|
||||
|
||||
for (DWORD dwY = 0; dwY < (DWORD)size.cy; dwY++) {
|
||||
WORD *pwTarget = (WORD *)pbTarget;
|
||||
PBYTE pbSource = pbBits + dwSourceStride * ((DWORD)size.cy - dwY - 1);
|
||||
for (DWORD dwX = 0; dwX < (DWORD)size.cx; dwX++) {
|
||||
if ( !((0x80 >> (dwX & 7)) & pbSource[dwX >> 3]) ) {
|
||||
pwTarget[dwX] = 0x0000; // Black
|
||||
}
|
||||
}
|
||||
pbTarget += lStrideInBytesTarget;
|
||||
}
|
||||
}
|
||||
delete [] pbBits;
|
||||
}
|
||||
|
||||
// Helper - compares media types - ignoring the advisory fields
|
||||
bool TypesMatch(const DMO_MEDIA_TYPE *pmt1, const DMO_MEDIA_TYPE *pmt2)
|
||||
{
|
||||
if (pmt1->majortype == pmt2->majortype &&
|
||||
pmt1->subtype == pmt2->subtype &&
|
||||
pmt1->lSampleSize == pmt2->lSampleSize &&
|
||||
pmt1->formattype == pmt2->formattype &&
|
||||
pmt1->cbFormat == pmt2->cbFormat &&
|
||||
0 == memcmp(pmt1->pbFormat, pmt2->pbFormat, pmt1->cbFormat)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Util.h
|
||||
//
|
||||
// Desc: DirectShow sample code - prototypes of utility routines.
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void GetVideoInfoParameters(
|
||||
const VIDEOINFOHEADER *pvih,
|
||||
PBYTE pbData,
|
||||
DWORD *pdwWidth,
|
||||
DWORD *pdwHeight,
|
||||
LONG *plStrideInBytes,
|
||||
BYTE **ppbTop
|
||||
);
|
||||
|
||||
void OurFillRect(const VIDEOINFOHEADER *pvih, PBYTE pbData, WORD wVal);
|
||||
|
||||
void DrawOurText(const VIDEOINFOHEADER * pvih, PBYTE pbData, LPCTSTR szBuffer);
|
||||
|
||||
PBYTE TextBitmap(LPCTSTR lpsz, SIZE *pSize);
|
||||
|
||||
// Helper
|
||||
bool TypesMatch(const DMO_MEDIA_TYPE *pmt1, const DMO_MEDIA_TYPE *pmt2);
|
||||
@@ -0,0 +1,100 @@
|
||||
# Microsoft Developer Studio Project File - Name="ControlBase" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=ControlBase - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ControlBase.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ControlBase.mak" CFG="ControlBase - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ControlBase - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ControlBase - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ControlBase - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ControlBase - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ControlBase - Win32 Release"
|
||||
# Name "ControlBase - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\controlhelp.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\controlhelp.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,224 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: ControlHelp.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CSliderValue and
|
||||
// CRadioChoice classes.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include "ControlHelp.h"
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <atlbase.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CSliderValue
|
||||
|
||||
const short g_sMaxContinuousTicks = 100;
|
||||
const int g_iMaxCharBuffer = 50; // # characters big enough to hold -FLT_MAX with room to spare
|
||||
|
||||
CSliderValue::CSliderValue()
|
||||
: m_fInit(false)
|
||||
{
|
||||
}
|
||||
|
||||
void CSliderValue::Init(
|
||||
HWND hwndSlider,
|
||||
HWND hwndEdit,
|
||||
float fMin,
|
||||
float fMax,
|
||||
bool fDiscrete)
|
||||
{
|
||||
m_hwndSlider = hwndSlider;
|
||||
m_hwndEdit = hwndEdit;
|
||||
m_fMin = fMin;
|
||||
m_fMax = fMax;
|
||||
m_fDiscrete = fDiscrete;
|
||||
|
||||
short sMin;
|
||||
short sMax;
|
||||
short sTicks = 4; // Lots of ticks become less useful as guides. Use quarters for fine-grained sliders.
|
||||
if (m_fDiscrete)
|
||||
{
|
||||
sMin = static_cast<short>(fMin);
|
||||
sMax = static_cast<short>(fMax);
|
||||
if (sMax - sMin <= 10)
|
||||
sTicks = (short) (sMax - sMin);
|
||||
}
|
||||
else
|
||||
{
|
||||
sMin = 0;
|
||||
sMax = g_sMaxContinuousTicks;
|
||||
}
|
||||
|
||||
SendMessage(m_hwndSlider, TBM_SETRANGE, TRUE, MAKELONG(sMin, sMax));
|
||||
SendMessage(m_hwndSlider, TBM_SETTICFREQ, (sMax - sMin) / sTicks, 0);
|
||||
m_fInit = true;
|
||||
}
|
||||
|
||||
void CSliderValue::SetValue(float fPos)
|
||||
{
|
||||
if (!m_fInit)
|
||||
return;
|
||||
|
||||
UpdateEditBox(fPos);
|
||||
UpdateSlider();
|
||||
}
|
||||
|
||||
float CSliderValue::GetValue()
|
||||
{
|
||||
if (!m_fInit)
|
||||
return 0;
|
||||
|
||||
LRESULT lrLen = SendMessage(m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);
|
||||
if (lrLen >= g_iMaxCharBuffer)
|
||||
return 0;
|
||||
|
||||
TCHAR szText[g_iMaxCharBuffer] = TEXT("");
|
||||
SendMessage(m_hwndEdit, WM_GETTEXT, g_iMaxCharBuffer, reinterpret_cast<LPARAM>(szText));
|
||||
|
||||
USES_CONVERSION;
|
||||
float fVal = static_cast<float>(m_fDiscrete ? _ttoi(szText) : atof(T2A(szText)));
|
||||
|
||||
if (fVal < m_fMin) fVal = m_fMin;
|
||||
if (fVal > m_fMax) fVal = m_fMax;
|
||||
return fVal;
|
||||
}
|
||||
|
||||
float CSliderValue::GetSliderValue()
|
||||
{
|
||||
short sPos = static_cast<short>(SendMessage(m_hwndSlider, TBM_GETPOS, 0, 0));
|
||||
if (m_fDiscrete)
|
||||
{
|
||||
return sPos;
|
||||
}
|
||||
|
||||
float fRet = (m_fMax - m_fMin) * sPos / g_sMaxContinuousTicks + m_fMin;
|
||||
return fRet;
|
||||
}
|
||||
|
||||
LRESULT CSliderValue::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (!m_fInit)
|
||||
return FALSE;
|
||||
|
||||
bHandled = FALSE;
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_HSCROLL:
|
||||
if (reinterpret_cast<HWND>(lParam) == m_hwndSlider && LOWORD(wParam) >= TB_LINEUP && LOWORD(wParam) <= TB_ENDTRACK)
|
||||
{
|
||||
UpdateEditBox(GetSliderValue());
|
||||
bHandled = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (HIWORD(wParam) == EN_KILLFOCUS && reinterpret_cast<HWND>(lParam) == m_hwndEdit)
|
||||
{
|
||||
UpdateSlider();
|
||||
bHandled = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSliderValue::UpdateEditBox(float fPos)
|
||||
{
|
||||
TCHAR szText[g_iMaxCharBuffer] = TEXT("");
|
||||
|
||||
if (m_fDiscrete)
|
||||
{
|
||||
short sPos = static_cast<short>(fPos);
|
||||
wsprintf(szText, TEXT("%hd"), sPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(szText, TEXT("%.3hf"), fPos);
|
||||
}
|
||||
|
||||
SendMessage(m_hwndEdit, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(szText));
|
||||
}
|
||||
|
||||
void CSliderValue::UpdateSlider()
|
||||
{
|
||||
float fVal = GetValue();
|
||||
short sPos = static_cast<short>(m_fDiscrete ? fVal : g_sMaxContinuousTicks * ((fVal - m_fMin) / (m_fMax - m_fMin)));
|
||||
SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, sPos);
|
||||
UpdateEditBox(fVal); // this resets the input box back to the set float value in case the input was invalid
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CSliderValue
|
||||
|
||||
CRadioChoice::CRadioChoice(const ButtonEntry *pButtonInfo)
|
||||
: m_pButtonInfo(pButtonInfo)
|
||||
{
|
||||
}
|
||||
|
||||
void CRadioChoice::SetChoice(HWND hDlg, LONG lValue)
|
||||
{
|
||||
for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
|
||||
{
|
||||
if (p->lValue == lValue)
|
||||
{
|
||||
CheckDlgButton(hDlg, p->nIDDlgItem, BST_CHECKED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LONG CRadioChoice::GetChoice(HWND hDlg)
|
||||
{
|
||||
for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
|
||||
{
|
||||
if (BST_CHECKED == IsDlgButtonChecked(hDlg, p->nIDDlgItem))
|
||||
{
|
||||
return p->lValue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CRadioChoice::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
bHandled = FALSE;
|
||||
UNREFERENCED_PARAMETER(lParam);
|
||||
|
||||
if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
for (const ButtonEntry *p = m_pButtonInfo; p->nIDDlgItem; ++p)
|
||||
{
|
||||
if (p->nIDDlgItem == LOWORD(wParam))
|
||||
{
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MessageHandlerChain
|
||||
|
||||
LRESULT MessageHandlerChain(Handler **ppHandlers, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
LRESULT lr = 0;
|
||||
bHandled = FALSE;
|
||||
|
||||
for (Handler **pp = ppHandlers; *pp && !bHandled; ++pp)
|
||||
{
|
||||
lr = (*pp)->MessageHandler(uMsg, wParam, lParam, bHandled);
|
||||
}
|
||||
return lr;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: ControlHelp.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definitions of CSliderValue and
|
||||
// CRadioChoice classes.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
virtual LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) = 0;
|
||||
};
|
||||
|
||||
class CSliderValue
|
||||
: public Handler
|
||||
{
|
||||
public:
|
||||
CSliderValue();
|
||||
void Init(HWND hwndSlider, HWND hwndEdit, float fMin, float fMax, bool fDiscrete);
|
||||
|
||||
void SetValue(float fPos);
|
||||
float GetValue();
|
||||
|
||||
LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
private:
|
||||
bool m_fInit;
|
||||
HWND m_hwndSlider;
|
||||
HWND m_hwndEdit;
|
||||
float m_fMin;
|
||||
float m_fMax;
|
||||
bool m_fDiscrete;
|
||||
|
||||
private:
|
||||
float GetSliderValue();
|
||||
void UpdateEditBox(float fPos);
|
||||
void UpdateSlider();
|
||||
};
|
||||
|
||||
class CRadioChoice
|
||||
: public Handler
|
||||
{
|
||||
public:
|
||||
struct ButtonEntry
|
||||
{
|
||||
int nIDDlgItem;
|
||||
LONG lValue;
|
||||
};
|
||||
|
||||
// Create passing a ButtonEntry array terminated by an entry with nIDDlgItem of 0.
|
||||
CRadioChoice(const ButtonEntry *pButtonInfo);
|
||||
|
||||
void SetChoice(HWND hDlg, LONG lValue);
|
||||
LONG GetChoice(HWND hDlg);
|
||||
|
||||
LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
private:
|
||||
const ButtonEntry *m_pButtonInfo;
|
||||
};
|
||||
|
||||
// MessageHandlerChain is a helper for implementing the property page message handler.
|
||||
// It takes a NULL-terminated array of Message pointers (could be CSliderValue or CRadioChoice)
|
||||
// and calls them in order until one of them sets bHandled.
|
||||
|
||||
LRESULT MessageHandlerChain(Handler **ppHandlers, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: GargDMOProp.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CGargDMOProp class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#define FIX_LOCK_NAME
|
||||
#include <param.h>
|
||||
#include <dmobase.h>
|
||||
#include "gargle.h"
|
||||
#include "GargDMOProp.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGargDMOProp
|
||||
|
||||
const CRadioChoice::ButtonEntry g_rgWaveButtons[] =
|
||||
{
|
||||
IDC_RADIO_TRIANGLE, GARGLE_FX_WAVE_TRIANGLE,
|
||||
IDC_RADIO_SQUARE, GARGLE_FX_WAVE_SQUARE,
|
||||
0
|
||||
};
|
||||
|
||||
CGargDMOProp::CGargDMOProp()
|
||||
: m_radioWaveform(g_rgWaveButtons),
|
||||
m_pIGargleFX( NULL )
|
||||
|
||||
{
|
||||
m_pUnkMarshaler = NULL;
|
||||
m_dwTitleID = IDS_TITLEGargDMOProp;
|
||||
m_dwHelpFileID = IDS_HELPFILEGargDMOProp;
|
||||
m_dwDocStringID = IDS_DOCSTRINGGargDMOProp;
|
||||
|
||||
m_rgpHandlers[0] = &m_sliderRate;
|
||||
m_rgpHandlers[1] = &m_radioWaveform;
|
||||
m_rgpHandlers[2] = NULL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CGargDMOProp::SetObjects(ULONG nObjects, IUnknown **ppUnk)
|
||||
{
|
||||
if (nObjects < 1 || nObjects > 1)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr = ppUnk[0]->QueryInterface(IID_IGargleDMOSample, reinterpret_cast<void**>(&m_pIGargleFX));
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CGargDMOProp::Apply(void)
|
||||
{
|
||||
if (!m_pIGargleFX)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
GargleFX garglefx;
|
||||
ZeroMemory(&garglefx, sizeof(GargleFX));
|
||||
|
||||
garglefx.dwRateHz = static_cast<DWORD>(m_sliderRate.GetValue());
|
||||
garglefx.dwWaveShape = m_radioWaveform.GetChoice(*this);
|
||||
|
||||
HRESULT hr = m_pIGargleFX->SetAllParameters(&garglefx);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
m_bDirty = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LRESULT CGargDMOProp::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (!m_pIGargleFX)
|
||||
return 1;
|
||||
|
||||
GargleFX garglefx;
|
||||
ZeroMemory(&garglefx, sizeof(GargleFX));
|
||||
m_pIGargleFX->GetAllParameters(&garglefx);
|
||||
|
||||
m_sliderRate.Init(GetDlgItem(IDC_SLIDER_Rate), GetDlgItem(IDC_EDIT_Rate), 1, 1000, true);
|
||||
m_sliderRate.SetValue(static_cast<float>(garglefx.dwRateHz));
|
||||
|
||||
m_radioWaveform.SetChoice(*this, garglefx.dwWaveShape);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
LRESULT CGargDMOProp::OnControlMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
LRESULT lr = MessageHandlerChain(m_rgpHandlers, uMsg, wParam, lParam, bHandled);
|
||||
|
||||
if (bHandled)
|
||||
SetDirty(TRUE);
|
||||
return lr;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: GargDMOProp.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definition of the CGargDMOProp class.
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __GARGDMOPROP_H_
|
||||
#define __GARGDMOPROP_H_
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include "controlhelp.h"
|
||||
|
||||
EXTERN_C const CLSID CLSID_GargDMOProp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGargDMOProp
|
||||
class ATL_NO_VTABLE CGargDMOProp :
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public CComCoClass<CGargDMOProp, &CLSID_GargDMOProp>,
|
||||
public IPropertyPageImpl<CGargDMOProp>,
|
||||
public CDialogImpl<CGargDMOProp>
|
||||
{
|
||||
public:
|
||||
|
||||
enum {IDD = IDD_GARGDMOPROP};
|
||||
|
||||
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_GARGDMOPROP)
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CGargDMOProp)
|
||||
COM_INTERFACE_ENTRY(IPropertyPage)
|
||||
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
|
||||
END_COM_MAP()
|
||||
|
||||
BEGIN_MSG_MAP(CGargDMOProp)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog);
|
||||
MESSAGE_HANDLER(WM_HSCROLL, OnControlMessage);
|
||||
MESSAGE_HANDLER(WM_COMMAND, OnControlMessage);
|
||||
CHAIN_MSG_MAP(IPropertyPageImpl<CGargDMOProp>)
|
||||
END_MSG_MAP()
|
||||
// Handler prototypes:
|
||||
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
|
||||
|
||||
CGargDMOProp();
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return CoCreateFreeThreadedMarshaler(
|
||||
GetControllingUnknown(), &m_pUnkMarshaler.p);
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
m_pUnkMarshaler.Release();
|
||||
}
|
||||
|
||||
CComPtr<IUnknown> m_pUnkMarshaler;
|
||||
|
||||
STDMETHOD(SetObjects)(ULONG nObjects, IUnknown **ppUnk);
|
||||
STDMETHOD(Apply)(void);
|
||||
|
||||
// Message handlers
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnControlMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
// Member variables
|
||||
CSliderValue m_sliderRate;
|
||||
CRadioChoice m_radioWaveform;
|
||||
Handler *m_rgpHandlers[3];
|
||||
CComPtr<IGargleDMOSample> m_pIGargleFX;
|
||||
|
||||
};
|
||||
|
||||
#endif //__GARGDMOPROP_H_
|
||||
@@ -0,0 +1,23 @@
|
||||
HKCR
|
||||
{
|
||||
GargleDMO.GargDMOProp.1 = s 'GargDMOProp Class'
|
||||
{
|
||||
CLSID = s '{3E7BB80F-2245-4483-ACC5-3A2EFDE0ACA6}'
|
||||
}
|
||||
GargleDMO.GargDMOProp = s 'GargDMOProp Class'
|
||||
{
|
||||
CLSID = s '{3E7BB80F-2245-4483-ACC5-3A2EFDE0ACA6}'
|
||||
CurVer = s 'GargleDMO.GargDMOProp.1'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {3E7BB80F-2245-4483-ACC5-3A2EFDE0ACA6} = s 'GargDMOProp Class'
|
||||
{
|
||||
ForceRemove 'Programmable'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Gargle.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of CGargle class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#define FIX_LOCK_NAME
|
||||
#include <dmo.h>
|
||||
#include <dmobase.h>
|
||||
#include <initguid.h> // needed to define GUID_TIME_REFERENCE from medparam.h
|
||||
#include <param.h>
|
||||
#include "Gargle.h"
|
||||
#include <uuids.h> // DirectShow media type guids
|
||||
|
||||
#define DEFAULT_GARGLE_RATE 20
|
||||
|
||||
#define CHECK_PARAM(lo, hi) \
|
||||
if (value < lo || value > hi) {return E_INVALIDARG;} ;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle
|
||||
//
|
||||
CGargle::CGargle( ) :
|
||||
m_ulShape(0),
|
||||
m_ulGargleFreqHz(DEFAULT_GARGLE_RATE),
|
||||
m_fDirty(true),
|
||||
m_bInitialized(FALSE)
|
||||
{
|
||||
m_pUnkMarshaler = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
HRESULT hr = Init();
|
||||
assert( SUCCEEDED( hr ) );
|
||||
#else
|
||||
Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
const MP_CAPS g_capsAll = MP_CAPS_CURVE_JUMP | MP_CAPS_CURVE_LINEAR | MP_CAPS_CURVE_SQUARE | MP_CAPS_CURVE_INVSQUARE | MP_CAPS_CURVE_SINE;
|
||||
static ParamInfo g_params[] =
|
||||
{
|
||||
// index type caps min, max, neutral, unit text, label, pwchText??
|
||||
GFP_Rate, MPT_INT, g_capsAll, GARGLE_FX_RATEHZ_MIN, GARGLE_FX_RATEHZ_MAX, 20, L"Hz", L"Rate", L"",
|
||||
GFP_Shape, MPT_ENUM, g_capsAll, GARGLE_FX_WAVE_TRIANGLE, GARGLE_FX_WAVE_SQUARE, GARGLE_FX_WAVE_TRIANGLE, L"", L"WaveShape", L"Triangle,Square",
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::Init
|
||||
//
|
||||
HRESULT CGargle::Init()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if( !m_bInitialized )
|
||||
{
|
||||
hr = InitParams(1, &GUID_TIME_REFERENCE, 0, 0, sizeof(g_params)/sizeof(*g_params), g_params);
|
||||
}
|
||||
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
// compute the period
|
||||
m_ulPeriod = m_ulSamplingRate / m_ulGargleFreqHz;
|
||||
m_bInitialized = TRUE;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::Clone
|
||||
//
|
||||
HRESULT CGargle::Clone(IMediaObjectInPlace **ppCloned)
|
||||
{
|
||||
if (!ppCloned)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
CGargle * pNewGargle = new CComObject<CGargle>;
|
||||
if( !pNewGargle )
|
||||
hr = E_OUTOFMEMORY;
|
||||
|
||||
hr = pNewGargle->Init();
|
||||
|
||||
IMediaObject * pCloned = NULL;
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
IUnknown *pUnk;
|
||||
hr = pNewGargle->QueryInterface( IID_IUnknown, (void **) &pUnk );
|
||||
if( SUCCEEDED( hr ) )
|
||||
{
|
||||
hr = pUnk->QueryInterface( IID_IMediaObject, (void **) &pCloned );
|
||||
pUnk->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy parameter control information
|
||||
//
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pNewGargle->CopyParamsFromSource((CParamsManager *) this);
|
||||
|
||||
// Copy current parameter values
|
||||
GargleFX params;
|
||||
if (SUCCEEDED(hr))
|
||||
hr = GetAllParameters(¶ms);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pNewGargle->SetAllParameters(¶ms);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Copy the input and output types
|
||||
DMO_MEDIA_TYPE mt;
|
||||
DWORD cInputStreams = 0;
|
||||
DWORD cOutputStreams = 0;
|
||||
GetStreamCount(&cInputStreams, &cOutputStreams);
|
||||
|
||||
for (DWORD i = 0; i < cInputStreams && SUCCEEDED(hr); ++i)
|
||||
{
|
||||
hr = GetInputCurrentType(i, &mt);
|
||||
if (hr == DMO_E_TYPE_NOT_SET)
|
||||
{
|
||||
hr = S_OK; // great, don't need to set the cloned DMO
|
||||
}
|
||||
else if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pCloned->SetInputType(i, &mt, 0);
|
||||
MoFreeMediaType( &mt );
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cOutputStreams && SUCCEEDED(hr); ++i)
|
||||
{
|
||||
hr = GetOutputCurrentType(i, &mt);
|
||||
if (hr == DMO_E_TYPE_NOT_SET)
|
||||
{
|
||||
hr = S_OK; // great, don't need to set the cloned DMO
|
||||
}
|
||||
else if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pCloned->SetOutputType(i, &mt, 0);
|
||||
MoFreeMediaType( &mt );
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pCloned->QueryInterface(IID_IMediaObjectInPlace, (void**)ppCloned);
|
||||
|
||||
// Release the object's original ref. If clone succeeded (made it through QI) then returned pointer
|
||||
// has one ref. If we failed, refs drop to zero, freeing the object.
|
||||
pCloned->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::GetLatency
|
||||
//
|
||||
STDMETHODIMP CGargle::GetLatency(THIS_ REFERENCE_TIME *prt)
|
||||
{
|
||||
*prt = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::Discontinuity
|
||||
//
|
||||
HRESULT CGargle::Discontinuity() {
|
||||
m_ulPhase = 0;
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::FBRProcess
|
||||
//
|
||||
HRESULT CGargle::FBRProcess(DWORD cQuanta, BYTE *pIn, BYTE *pOut) {
|
||||
if (!m_bInitialized)
|
||||
return DMO_E_TYPE_NOT_SET;
|
||||
|
||||
DWORD cSample, cChannel;
|
||||
for (cSample = 0; cSample < cQuanta; cSample++)
|
||||
{
|
||||
// If m_Shape is 0 (triangle) then we multiply by a triangular waveform
|
||||
// that runs 0..Period/2..0..Period/2..0... else by a square one that
|
||||
// is either 0 or Period/2 (same maximum as the triangle) or zero.
|
||||
//
|
||||
// m_Phase is the number of samples from the start of the period.
|
||||
// We keep this running from one call to the next,
|
||||
// but if the period changes so as to make this more
|
||||
// than Period then we reset to 0 with a bang. This may cause
|
||||
// an audible click or pop (but, hey! it's only a sample!)
|
||||
//
|
||||
++m_ulPhase;
|
||||
if (m_ulPhase > m_ulPeriod)
|
||||
m_ulPhase = 0;
|
||||
|
||||
ULONG ulM = m_ulPhase; // m is what we modulate with
|
||||
|
||||
if (m_ulShape == 0) { // Triangle
|
||||
if (ulM > m_ulPeriod / 2)
|
||||
ulM = m_ulPeriod - ulM; // handle downslope
|
||||
} else { // Square wave
|
||||
if (ulM <= m_ulPeriod / 2)
|
||||
ulM = m_ulPeriod / 2;
|
||||
else
|
||||
ulM = 0;
|
||||
}
|
||||
|
||||
for (cChannel = 0; cChannel < m_cChannels; cChannel++) {
|
||||
if (m_b8bit) {
|
||||
// sound sample, zero based
|
||||
int i = pIn[cSample * m_cChannels + cChannel] - 128;
|
||||
// modulate
|
||||
i = (i * (signed)ulM * 2) / (signed)m_ulPeriod;
|
||||
// 8 bit sound uses 0..255 representing -128..127
|
||||
// Any overflow, even by 1, would sound very bad.
|
||||
// so we clip paranoically after modulating.
|
||||
// I think it should never clip by more than 1
|
||||
//
|
||||
if (i > 127)
|
||||
i = 127;
|
||||
if (i < -128)
|
||||
i = -128;
|
||||
// reset zero offset to 128
|
||||
pOut[cSample * m_cChannels + cChannel] = (unsigned char)(i + 128);
|
||||
|
||||
} else {
|
||||
// 16 bit sound uses 16 bits properly (0 means 0)
|
||||
// We still clip paranoically
|
||||
//
|
||||
int i = ((short*)pIn)[cSample * m_cChannels + cChannel];
|
||||
// modulate
|
||||
i = (i * (signed)ulM * 2) / (signed)m_ulPeriod;
|
||||
// clip
|
||||
if (i > 32767)
|
||||
i = 32767;
|
||||
if (i < -32768)
|
||||
i = -32768;
|
||||
((short*)pOut)[cSample * m_cChannels + cChannel] = (short)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetClassID
|
||||
//
|
||||
HRESULT CGargle::GetClassID(CLSID *pClsid)
|
||||
{
|
||||
if (pClsid==NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
*pClsid = CLSID_Gargle;
|
||||
return NOERROR;
|
||||
|
||||
} // GetClassID
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::GetPages
|
||||
//
|
||||
HRESULT CGargle::GetPages(CAUUID * pPages)
|
||||
{
|
||||
pPages->cElems = 1;
|
||||
pPages->pElems = static_cast<GUID *>(CoTaskMemAlloc(sizeof(GUID)));
|
||||
if (pPages->pElems == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
*(pPages->pElems) = CLSID_GargDMOProp;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::SetAllParameters
|
||||
//
|
||||
STDMETHODIMP CGargle::SetAllParameters(THIS_ LPCGargleFX pParm)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Check that the pointer is not NULL
|
||||
if (pParm == NULL) hr = E_POINTER;
|
||||
|
||||
// Set the parameters
|
||||
if (SUCCEEDED(hr)) hr = SetParam(GFP_Rate, static_cast<MP_DATA>(pParm->dwRateHz));
|
||||
if (SUCCEEDED(hr)) hr = SetParam(GFP_Shape, static_cast<MP_DATA>(pParm->dwWaveShape));
|
||||
|
||||
m_fDirty = true;
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::GetAllParameters
|
||||
//
|
||||
STDMETHODIMP CGargle::GetAllParameters(THIS_ LPGargleFX pParm)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
MP_DATA var;
|
||||
|
||||
if (pParm == NULL)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
#define GET_PARAM_DWORD(x,y) \
|
||||
if (SUCCEEDED(hr)) { \
|
||||
hr = GetParam(x, &var); \
|
||||
if (SUCCEEDED(hr)) pParm->y = (DWORD)var; \
|
||||
}
|
||||
|
||||
GET_PARAM_DWORD(GFP_Rate, dwRateHz);
|
||||
GET_PARAM_DWORD(GFP_Shape, dwWaveShape);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::SetParam
|
||||
//
|
||||
HRESULT CGargle::SetParamInternal(DWORD dwParamIndex, MP_DATA value, bool fSkipPasssingToParamManager)
|
||||
{
|
||||
switch (dwParamIndex)
|
||||
{
|
||||
case GFP_Rate:
|
||||
CHECK_PARAM(GARGLE_FX_RATEHZ_MIN,GARGLE_FX_RATEHZ_MAX);
|
||||
m_ulGargleFreqHz = (unsigned)value;
|
||||
if (m_ulGargleFreqHz < 1) m_ulGargleFreqHz = 1;
|
||||
if (m_ulGargleFreqHz > 1000) m_ulGargleFreqHz = 1000;
|
||||
|
||||
// Init is where m_ulPeriod is updated, so call it here
|
||||
// Would be better to do this outside of Init though
|
||||
Init();
|
||||
break;
|
||||
|
||||
case GFP_Shape:
|
||||
CHECK_PARAM(GARGLE_FX_WAVE_TRIANGLE,GARGLE_FX_WAVE_SQUARE);
|
||||
m_ulShape = (unsigned)value;
|
||||
break;
|
||||
}
|
||||
|
||||
// Let base class set this so it can handle all the rest of the param calls.
|
||||
// Skip the base class if fSkipPasssingToParamManager. This indicates that we're calling the function
|
||||
// internally using values that came from the base class -- thus there's no need to tell it values it
|
||||
// already knows.
|
||||
return fSkipPasssingToParamManager ? S_OK : CParamsManager::SetParam(dwParamIndex, value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CGargle::Process
|
||||
//
|
||||
HRESULT CGargle::Process(ULONG ulQuanta, LPBYTE pcbData, REFERENCE_TIME rtStart, DWORD dwFlags)
|
||||
{
|
||||
// Update parameter values from any curves that may be in effect.
|
||||
// We pick up the current values stored in the CParamsManager helper for time rtStart.
|
||||
|
||||
// Note that we are using IMediaParams in a less than
|
||||
// perfect way. We update at the beginning of every time slice instead of smoothly over the curve.
|
||||
// This is okay for an effect like gargle as long as the time slice is consistently small (which
|
||||
// it conveniently is when hosted in DSound.)
|
||||
// However, in the future we will update this sample to use a more appropriate and accurate
|
||||
// mechanism.
|
||||
// Here are some suggestions of how it can be done, with increasing degree of accuracy. Different
|
||||
// types of effects and effect parameters require different levels of accuracy, so no solution is the best
|
||||
// solution for all (especially if you are concerned about CPU cost.)
|
||||
// 1) Break the time slice up into mini pieces of some number of milliseconds
|
||||
// each and run through all the steps in Process for each sub slice. This guarantees the
|
||||
// stair stepping is small enough not to be noticable. This approach will work well for parameters
|
||||
// that don't create an audible stair stepping noise (or "zipper") noise when controled in this way.
|
||||
// Control over volume, for example, does not work well.
|
||||
// 2) Use the above mechanism, but pass the start and end values for each parameter to the
|
||||
// processing engine. It, in turn, applies linear interpolation to each parameter. This results
|
||||
// in a smooth approximation of the parameter curve and removes all but the most subtle aliasing noise.
|
||||
// 3) Pass the curves directly to the processing engine, which accurately calculates each sample
|
||||
// mathematically. This is obviously the best, but most complex and CPU intensive.
|
||||
|
||||
this->UpdateActiveParams(rtStart, *this);
|
||||
|
||||
DMO_MEDIA_TYPE mt;
|
||||
HRESULT hr = GetInputCurrentType(0, &mt);
|
||||
if( FAILED( hr ) )
|
||||
return hr;
|
||||
|
||||
// convert bytes to samples for the FBRProcess call
|
||||
assert(mt.formattype == FORMAT_WaveFormatEx);
|
||||
ulQuanta /= LPWAVEFORMATEX(mt.pbFormat)->nBlockAlign;
|
||||
MoFreeMediaType( &mt );
|
||||
return FBRProcess(ulQuanta, pcbData, pcbData);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Gargle.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definition of CGargle class.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __GARGLE_H_
|
||||
#define __GARGLE_H_
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include "igargle.h" // interface to us
|
||||
|
||||
// {458F93F3-4769-4370-8A7D-D055EE97679C}
|
||||
DEFINE_GUID(CLSID_Gargle,
|
||||
0x458f93f3, 0x4769, 0x4370, 0x8a, 0x7d, 0xd0, 0x55, 0xee, 0x97, 0x67, 0x9c);
|
||||
|
||||
// {3E7BB80F-2245-4483-ACC5-3A2EFDE0ACA6}
|
||||
DEFINE_GUID(CLSID_GargDMOProp,
|
||||
0x3e7bb80f, 0x2245, 0x4483, 0xac, 0xc5, 0x3a, 0x2e, 0xfd, 0xe0, 0xac, 0xa6);
|
||||
|
||||
enum GargleFilterParams
|
||||
{
|
||||
GFP_Rate = 0,
|
||||
GFP_Shape,
|
||||
GFP_MAX
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CGargle
|
||||
class ATL_NO_VTABLE CGargle :
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public CComCoClass<CGargle, &CLSID_Gargle>,
|
||||
public CPCMDMO,
|
||||
public ISpecifyPropertyPages,
|
||||
public IPersistStream,
|
||||
public IMediaObjectInPlace,
|
||||
public CParamsManager,
|
||||
public CParamsManager::UpdateCallback,
|
||||
public IGargleDMOSample // property page uses this to talk to us
|
||||
{
|
||||
public:
|
||||
CGargle();
|
||||
HRESULT Init();
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_GARGLE)
|
||||
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CGargle)
|
||||
COM_INTERFACE_ENTRY(IMediaObject)
|
||||
COM_INTERFACE_ENTRY(IMediaObjectInPlace)
|
||||
COM_INTERFACE_ENTRY(IMediaParams)
|
||||
COM_INTERFACE_ENTRY(IMediaParamInfo)
|
||||
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
|
||||
COM_INTERFACE_ENTRY(IPersistStream)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IGargleDMOSample, IGargleDMOSample)
|
||||
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
|
||||
END_COM_MAP()
|
||||
|
||||
HRESULT FinalConstruct()
|
||||
{
|
||||
return CoCreateFreeThreadedMarshaler(
|
||||
GetControllingUnknown(), &m_pUnkMarshaler.p);
|
||||
}
|
||||
|
||||
void FinalRelease()
|
||||
{
|
||||
m_pUnkMarshaler.Release();
|
||||
}
|
||||
|
||||
CComPtr<IUnknown> m_pUnkMarshaler;
|
||||
|
||||
HRESULT FBRProcess(DWORD cSamples, BYTE *pIn, BYTE *pOut);
|
||||
|
||||
// override
|
||||
HRESULT Discontinuity();
|
||||
|
||||
bool m_fDirty;
|
||||
|
||||
// IGargleDMOSample
|
||||
STDMETHOD(SetAllParameters) (THIS_ LPCGargleFX);
|
||||
STDMETHOD(GetAllParameters) (THIS_ LPGargleFX);
|
||||
|
||||
// IMediaObjectInPlace
|
||||
STDMETHODIMP Process(THIS_ ULONG ulSize, BYTE *pData, REFERENCE_TIME rtStart, DWORD dwFlags);
|
||||
STDMETHODIMP GetLatency(THIS_ REFERENCE_TIME *prt);
|
||||
STDMETHODIMP Clone(IMediaObjectInPlace **pp);
|
||||
|
||||
// SetParam handling
|
||||
STDMETHODIMP SetParam(DWORD dwParamIndex,MP_DATA value) { return SetParamInternal(dwParamIndex, value, false); }
|
||||
HRESULT SetParamUpdate(DWORD dwParamIndex, MP_DATA value) { return SetParamInternal(dwParamIndex, value, true); }
|
||||
HRESULT SetParamInternal(DWORD dwParamIndex, MP_DATA value, bool fSkipPasssingToParamManager);
|
||||
|
||||
// ISpecifyPropertyPages
|
||||
STDMETHODIMP GetPages(CAUUID * pPages);
|
||||
|
||||
/* IPersist */
|
||||
STDMETHODIMP GetClassID(THIS_ CLSID *pClassID);
|
||||
|
||||
// IPersistStream
|
||||
STDMETHOD(IsDirty)(void) { return m_fDirty ? S_OK : S_FALSE; }
|
||||
|
||||
STDMETHOD(Load)(IStream *pStm)
|
||||
{
|
||||
ULONG cbRead;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (pStm==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
GargleFX garglefx;
|
||||
hr = pStm->Read((void *)&garglefx, sizeof(garglefx), &cbRead);
|
||||
if (hr != S_OK || cbRead < sizeof(garglefx))
|
||||
return E_FAIL;
|
||||
hr = SetAllParameters(&garglefx);
|
||||
m_fDirty = false;
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (pStm==NULL)
|
||||
return E_POINTER;
|
||||
|
||||
GargleFX garglefx;
|
||||
hr = GetAllParameters(&garglefx);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
ULONG cbWritten;
|
||||
hr = pStm->Write((void *)&garglefx, sizeof(garglefx), &cbWritten);
|
||||
if (hr != S_OK || cbWritten < sizeof(garglefx))
|
||||
return E_FAIL;
|
||||
|
||||
if (fClearDirty)
|
||||
m_fDirty = false;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize)
|
||||
{
|
||||
if (!pcbSize)
|
||||
return E_POINTER;
|
||||
|
||||
pcbSize->QuadPart = sizeof(GargleFX);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
// gargle params
|
||||
ULONG m_ulShape;
|
||||
ULONG m_ulGargleFreqHz;
|
||||
|
||||
// gargle state
|
||||
ULONG m_ulPeriod;
|
||||
ULONG m_ulPhase;
|
||||
|
||||
BOOL m_bInitialized;
|
||||
|
||||
};
|
||||
|
||||
#endif //__GARGLE_H_
|
||||
@@ -0,0 +1,26 @@
|
||||
HKCR
|
||||
{
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {458F93F3-4769-4370-8A7D-D055EE97679C} = s 'CGargle Class'
|
||||
{
|
||||
ForceRemove 'Programmable'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Both'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {3E7BB80F-2245-4483-ACC5-3A2EFDE0ACA6} = s 'GargDMOProp Class'
|
||||
{
|
||||
ForceRemove 'Programmable'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'Both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: GargleDMO.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of DLL exports.
|
||||
//
|
||||
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Note: Proxy/Stub Information
|
||||
// To build a separate proxy/stub DLL,
|
||||
// run nmake -f GargleDMOps.mk in the project directory.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#define FIX_LOCK_NAME
|
||||
#include <dmo.h>
|
||||
#include <dmobase.h>
|
||||
#include <param.h>
|
||||
#include "Gargle.h"
|
||||
#include "GargDMOProp.h"
|
||||
|
||||
CComModule _Module;
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_Gargle, CGargle)
|
||||
OBJECT_ENTRY(CLSID_GargDMOProp, CGargDMOProp)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Point
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
_Module.Init(ObjectMap, hInstance);
|
||||
DisableThreadLibraryCalls(hInstance);
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH)
|
||||
_Module.Term();
|
||||
return TRUE; // ok
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Returns a class factory to create an object of the requested type
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
return _Module.GetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllRegisterServer - Adds entries to the system registry
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
// Register ourselves as a pcm audio effects DMO
|
||||
DMO_PARTIAL_MEDIATYPE mt;
|
||||
mt.type = MEDIATYPE_Audio;
|
||||
mt.subtype = MEDIASUBTYPE_PCM;
|
||||
|
||||
DMORegister(L"Gargle DMO Sample",
|
||||
CLSID_Gargle,
|
||||
DMOCATEGORY_AUDIO_EFFECT,
|
||||
0,
|
||||
1,
|
||||
&mt,
|
||||
1,
|
||||
&mt);
|
||||
|
||||
// registers object, but we're not using a typelib
|
||||
return _Module.RegisterServer(FALSE);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllUnregisterServer - Removes entries from the system registry
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
return _Module.UnregisterServer(TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
; GargleDMO.def : Declares the module parameters.
|
||||
|
||||
LIBRARY "GargleDMO.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
@@ -0,0 +1,221 @@
|
||||
# Microsoft Developer Studio Project File - Name="GargleDMO" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=GargleDMO - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "GargleDMO.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "GargleDMO.mak" CFG="GargleDMO - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "GargleDMO - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "GargleDMO - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\..\..\lib"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
# Begin Custom Build - Performing registration
|
||||
OutDir=.\Debug
|
||||
TargetPath=.\Debug\GargleDMO.dll
|
||||
InputPath=.\Debug\GargleDMO.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "..\dsdmobase\inc" /I "medparambase" /I "controlbase" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MD /W3 /O2 /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\..\..\lib" /libpath:"controlbase"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /stack:0x200000,0x200000 /subsystem:windows /dll /pdb:none /machine:I386 /libpath:"..\..\..\..\..\lib"
|
||||
# SUBTRACT LINK32 /map /nodefaultlib
|
||||
# Begin Custom Build - Performing registration
|
||||
OutDir=.\Release
|
||||
TargetPath=.\Release\GargleDMO.dll
|
||||
InputPath=.\Release\GargleDMO.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "GargleDMO - Win32 Debug"
|
||||
# Name "GargleDMO - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargDMOProp.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
# ADD CPP /D "NDEBUG"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Gargle.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
# ADD CPP /D "NDEBUG"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargleDMO.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
# ADD CPP /D "NDEBUG"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargleDMO.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargleDMO.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
# ADD CPP /D "NDEBUG" /Yc"stdafx.h"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargDMOProp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Gargle.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\igargle.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\GargDMOProp.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Gargle.rgs
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
# Section GargleDMO : {00000000-0000-0000-0000-800000800000}
|
||||
# 1:15:IDR_GARGDMOPROP:106
|
||||
# 1:20:IDS_TITLEGargDMOProp:103
|
||||
# 1:15:IDD_GARGDMOPROP:107
|
||||
# 1:24:IDS_DOCSTRINGGargDMOProp:105
|
||||
# 1:23:IDS_HELPFILEGargDMOProp:104
|
||||
# End Section
|
||||
@@ -0,0 +1,59 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ControlBase"=.\ControlBase\ControlBase.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "GargleDMO"=.\GargleDMO.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name MedParamBase
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name ControlBase
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "MedParamBase"=.\MedParamBase\MedParamBase.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Based on GargleDMO.dsp
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=GargleDMO - Win32 Release
|
||||
!MESSAGE No configuration specified. Defaulting to GargleDMO - Win32 Release.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "GargleDMO - Win32 Debug" && "$(CFG)" != "GargleDMO - Win32 Release"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "GargleDMO.mak" CFG="GargleDMO - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "GargleDMO - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "GargleDMO - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\GargleDMO.dll" ".\Debug\regsvr32.trg"
|
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "ControlBase - Win32 Debug" "MedParamBase - Win32 Debug" "$(OUTDIR)\GargleDMO.dll" ".\Debug\regsvr32.trg"
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"MedParamBase - Win32 DebugCLEAN" "ControlBase - Win32 DebugCLEAN"
|
||||
!ELSE
|
||||
CLEAN :
|
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\GargDMOProp.obj"
|
||||
-@erase "$(INTDIR)\Gargle.obj"
|
||||
-@erase "$(INTDIR)\GargleDMO.obj"
|
||||
-@erase "$(INTDIR)\GargleDMO.pch"
|
||||
-@erase "$(INTDIR)\GargleDMO.res"
|
||||
-@erase "$(INTDIR)\StdAfx.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\GargleDMO.dll"
|
||||
-@erase "$(OUTDIR)\GargleDMO.exp"
|
||||
-@erase "$(OUTDIR)\GargleDMO.ilk"
|
||||
-@erase "$(OUTDIR)\GargleDMO.lib"
|
||||
-@erase "$(OUTDIR)\GargleDMO.pdb"
|
||||
-@erase ".\Debug\regsvr32.trg"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\GargleDMO.res" /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\GargleDMO.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\GargleDMO.pdb" /debug /machine:I386 /def:".\GargleDMO.def" /out:"$(OUTDIR)\GargleDMO.dll" /implib:"$(OUTDIR)\GargleDMO.lib" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
DEF_FILE= \
|
||||
".\GargleDMO.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\GargDMOProp.obj" \
|
||||
"$(INTDIR)\Gargle.obj" \
|
||||
"$(INTDIR)\GargleDMO.obj" \
|
||||
"$(INTDIR)\StdAfx.obj" \
|
||||
"$(INTDIR)\GargleDMO.res" \
|
||||
".\MedParamBase\Debug\MedParamBase.lib" \
|
||||
".\ControlBase\Debug\ControlBase.lib"
|
||||
|
||||
"$(OUTDIR)\GargleDMO.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
OutDir=.\Debug
|
||||
TargetPath=.\Debug\GargleDMO.dll
|
||||
InputPath=.\Debug\GargleDMO.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OUTDIR)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
<<
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\GargleDMO.dll" ".\Release\regsvr32.trg"
|
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "ControlBase - Win32 Release" "MedParamBase - Win32 Release" "$(OUTDIR)\GargleDMO.dll" ".\Release\regsvr32.trg"
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"MedParamBase - Win32 ReleaseCLEAN" "ControlBase - Win32 ReleaseCLEAN"
|
||||
!ELSE
|
||||
CLEAN :
|
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\GargDMOProp.obj"
|
||||
-@erase "$(INTDIR)\Gargle.obj"
|
||||
-@erase "$(INTDIR)\GargleDMO.obj"
|
||||
-@erase "$(INTDIR)\GargleDMO.pch"
|
||||
-@erase "$(INTDIR)\GargleDMO.res"
|
||||
-@erase "$(INTDIR)\StdAfx.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\GargleDMO.dll"
|
||||
-@erase "$(OUTDIR)\GargleDMO.exp"
|
||||
-@erase "$(OUTDIR)\GargleDMO.lib"
|
||||
-@erase ".\Release\regsvr32.trg"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MD /W3 /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
MTL=midl.exe
|
||||
MTL_PROJ=
|
||||
RSC=rc.exe
|
||||
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\GargleDMO.res" /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\GargleDMO.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib msdmo.lib dmoguids.lib strmiids.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\GargleDMO.pdb" /machine:I386 /def:".\GargleDMO.def" /out:"$(OUTDIR)\GargleDMO.dll" /implib:"$(OUTDIR)\GargleDMO.lib" /pdbtype:sept /libpath:"..\..\..\..\..\lib" /stack:0x200000,0x200000
|
||||
DEF_FILE= \
|
||||
".\GargleDMO.def"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\GargDMOProp.obj" \
|
||||
"$(INTDIR)\Gargle.obj" \
|
||||
"$(INTDIR)\GargleDMO.obj" \
|
||||
"$(INTDIR)\StdAfx.obj" \
|
||||
"$(INTDIR)\GargleDMO.res" \
|
||||
".\MedParamBase\Release\MedParamBase.lib" \
|
||||
".\ControlBase\Release\ControlBase.lib"
|
||||
|
||||
"$(OUTDIR)\GargleDMO.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<<
|
||||
|
||||
OutDir=.\Release
|
||||
TargetPath=.\Release\GargleDMO.dll
|
||||
InputPath=.\Release\GargleDMO.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OUTDIR)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1"
|
||||
!IF EXISTS("GargleDMO.dep")
|
||||
!INCLUDE "GargleDMO.dep"
|
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "GargleDMO.dep"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug" || "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
SOURCE=.\GargDMOProp.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
CPP_SWITCHES=/nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\GargDMOProp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
CPP_SWITCHES=/nologo /MD /W3 /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDEBUG" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\GargDMOProp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\Gargle.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
CPP_SWITCHES=/nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\Gargle.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
CPP_SWITCHES=/nologo /MD /W3 /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDEBUG" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\Gargle.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\GargleDMO.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
CPP_SWITCHES=/nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\GargleDMO.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
CPP_SWITCHES=/nologo /MD /W3 /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDEBUG" /Fp"$(INTDIR)\GargleDMO.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\GargleDMO.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GargleDMO.pch"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\GargleDMO.rc
|
||||
|
||||
"$(INTDIR)\GargleDMO.res" : $(SOURCE) "$(INTDIR)"
|
||||
$(RSC) $(RSC_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
CPP_SWITCHES=/nologo /MDd /W3 /Gm /Zi /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fp"$(INTDIR)\GargleDMO.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\GargleDMO.pch" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
CPP_SWITCHES=/nologo /MD /W3 /Od /I "..\..\..\..\..\include" /I "medparambase" /I "controlbase" /I "dmobase" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NDEBUG" /Fp"$(INTDIR)\GargleDMO.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\GargleDMO.pch" : $(SOURCE) "$(INTDIR)"
|
||||
$(CPP) @<<
|
||||
$(CPP_SWITCHES) $(SOURCE)
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
"MedParamBase - Win32 Debug" :
|
||||
cd ".\MedParamBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\MedParamBase.mak CFG="MedParamBase - Win32 Debug"
|
||||
cd ".."
|
||||
|
||||
"MedParamBase - Win32 DebugCLEAN" :
|
||||
cd ".\MedParamBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\MedParamBase.mak CFG="MedParamBase - Win32 Debug" RECURSE=1 CLEAN
|
||||
cd ".."
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
"MedParamBase - Win32 Release" :
|
||||
cd ".\MedParamBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\MedParamBase.mak CFG="MedParamBase - Win32 Release"
|
||||
cd ".."
|
||||
|
||||
"MedParamBase - Win32 ReleaseCLEAN" :
|
||||
cd ".\MedParamBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\MedParamBase.mak CFG="MedParamBase - Win32 Release" RECURSE=1 CLEAN
|
||||
cd ".."
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "GargleDMO - Win32 Debug"
|
||||
|
||||
"ControlBase - Win32 Debug" :
|
||||
cd ".\ControlBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\ControlBase.mak CFG="ControlBase - Win32 Debug"
|
||||
cd ".."
|
||||
|
||||
"ControlBase - Win32 DebugCLEAN" :
|
||||
cd ".\ControlBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\ControlBase.mak CFG="ControlBase - Win32 Debug" RECURSE=1 CLEAN
|
||||
cd ".."
|
||||
|
||||
!ELSEIF "$(CFG)" == "GargleDMO - Win32 Release"
|
||||
|
||||
"ControlBase - Win32 Release" :
|
||||
cd ".\ControlBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\ControlBase.mak CFG="ControlBase - Win32 Release"
|
||||
cd ".."
|
||||
|
||||
"ControlBase - Win32 ReleaseCLEAN" :
|
||||
cd ".\ControlBase"
|
||||
$(MAKE) /$(MAKEFLAGS) /F .\ControlBase.mak CFG="ControlBase - Win32 Release" RECURSE=1 CLEAN
|
||||
cd ".."
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"1 TYPELIB ""GargleDMO.tlb""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 8,1,0,0
|
||||
PRODUCTVERSION 8,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "Comments", "DirectShow Sample\0"
|
||||
VALUE "CompanyName", "Microsoft\0"
|
||||
VALUE "FileDescription", "GargleDMO Sample\0"
|
||||
VALUE "FileVersion", "8.10\0"
|
||||
VALUE "InternalName", "GargleDMO\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2000-2001 Microsoft Corporation\0"
|
||||
VALUE "OriginalFilename", "GargleDMO.DLL\0"
|
||||
VALUE "ProductName", "DirectX 8 SDK\0"
|
||||
VALUE "ProductVersion", "8.1\0"
|
||||
VALUE "OLESelfRegister", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REGISTRY
|
||||
//
|
||||
|
||||
IDR_GARGLE REGISTRY DISCARDABLE "Gargle.rgs"
|
||||
IDR_GARGDMOPROP REGISTRY DISCARDABLE "GargDMOProp.rgs"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_GARGDMOPROP DIALOGEX 0, 0, 225, 71
|
||||
STYLE WS_CHILD
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x1
|
||||
BEGIN
|
||||
RTEXT "Waveform:",IDC_STATIC,2,15,43,10,SS_CENTERIMAGE
|
||||
CONTROL "&Square",IDC_RADIO_SQUARE,"Button",BS_AUTORADIOBUTTON,
|
||||
50,15,38,10
|
||||
CONTROL "&Triangle",IDC_RADIO_TRIANGLE,"Button",
|
||||
BS_AUTORADIOBUTTON,90,15,41,10
|
||||
RTEXT "&Rate (Hz):",IDC_STATIC,2,45,43,14,SS_CENTERIMAGE
|
||||
EDITTEXT IDC_EDIT_Rate,50,45,35,14,ES_AUTOHSCROLL
|
||||
CONTROL "Slider1",IDC_SLIDER_Rate,"msctls_trackbar32",
|
||||
TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,90,45,130,19
|
||||
CTEXT "1",IDC_STATIC,87,37,19,8
|
||||
CTEXT "1000",IDC_STATIC,202,37,19,8
|
||||
END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_PROJNAME "GargleDMO"
|
||||
IDS_TITLEGargDMOProp "Gargle DMO Sample"
|
||||
IDS_DOCSTRINGGargDMOProp "property page for Gargle DMO Sample"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# Microsoft Developer Studio Project File - Name="MedParamBase" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=MedParamBase - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MedParamBase.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MedParamBase.mak" CFG="MedParamBase - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "MedParamBase - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "MedParamBase - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "MedParamBase - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "MedParamBase - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "MedParamBase - Win32 Release"
|
||||
# Name "MedParamBase - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\alist.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\param.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\alist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\param.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\validate.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AList.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - implementation of AListItem and AList
|
||||
// classes.
|
||||
//
|
||||
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include "alist.h"
|
||||
|
||||
LONG AListItem::GetCount(void) const
|
||||
{
|
||||
LONG l;
|
||||
const AListItem *li;
|
||||
|
||||
for(l=0,li=this; li!=NULL ; li=li->m_pNext,++l);
|
||||
return l;
|
||||
}
|
||||
|
||||
AListItem* AListItem::Cat(AListItem *pItem)
|
||||
{
|
||||
AListItem *li;
|
||||
|
||||
if(this==NULL)
|
||||
return pItem;
|
||||
for(li=this ; li->m_pNext!=NULL ; li=li->m_pNext);
|
||||
li->m_pNext=pItem;
|
||||
return this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// AListItem::Remove
|
||||
|
||||
AListItem* AListItem::Remove(AListItem *pItem)
|
||||
{
|
||||
AListItem *li,*prev;
|
||||
|
||||
//treat remove(NULL) same as item not found in list
|
||||
if (pItem==NULL)
|
||||
return this;
|
||||
|
||||
if(pItem==this)
|
||||
return m_pNext;
|
||||
prev=NULL;
|
||||
for(li=this; li!=NULL && li!=pItem ; li=li->m_pNext)
|
||||
prev=li;
|
||||
if(li==NULL) // item not found in list
|
||||
return this;
|
||||
|
||||
// here it is guaranteed that prev is non-NULL since we checked for
|
||||
// that condition at the very beginning
|
||||
|
||||
prev->SetNext(li->m_pNext);
|
||||
li->SetNext(NULL);
|
||||
|
||||
// SetNext on pItem to NULL
|
||||
pItem->SetNext(NULL);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
AListItem* AListItem::GetPrev(AListItem *pItem) const
|
||||
{
|
||||
const AListItem *li,*prev;
|
||||
|
||||
prev=NULL;
|
||||
for(li=this ; li!=NULL && li!=pItem ; li=li->m_pNext)
|
||||
prev=li;
|
||||
return (AListItem*)prev;
|
||||
}
|
||||
|
||||
AListItem * AListItem::GetItem(LONG index)
|
||||
|
||||
{
|
||||
AListItem *scan;
|
||||
for (scan = this; scan!=NULL && index; scan = scan->m_pNext)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
return (scan);
|
||||
}
|
||||
|
||||
void AList::InsertBefore(AListItem *pItem,AListItem *pInsert)
|
||||
|
||||
{
|
||||
AListItem *prev = GetPrev(pItem);
|
||||
pInsert->SetNext(pItem);
|
||||
if (prev) prev->SetNext(pInsert);
|
||||
else m_pHead = pInsert;
|
||||
}
|
||||
|
||||
|
||||
void AList::AddTail(AListItem *pItem)
|
||||
{
|
||||
if (m_pHead == NULL)
|
||||
{
|
||||
AddHead(pItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pHead = m_pHead->AddTail(pItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AList::Reverse()
|
||||
|
||||
{
|
||||
AList Temp;
|
||||
AListItem *pItem;
|
||||
while ((pItem = RemoveHead()) != 0)
|
||||
{
|
||||
Temp.AddHead(pItem);
|
||||
}
|
||||
Cat(Temp.GetHead());
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: AList.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definitions of AListItem and AList classes.
|
||||
//
|
||||
// Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __ALIST_H__
|
||||
#define __ALIST_H__
|
||||
|
||||
class AListItem
|
||||
{
|
||||
public:
|
||||
AListItem() { m_pNext=NULL; };
|
||||
AListItem *GetNext() const {return m_pNext;};
|
||||
void SetNext(AListItem *pNext) {m_pNext=pNext;};
|
||||
LONG GetCount() const;
|
||||
AListItem* Cat(AListItem* pItem);
|
||||
AListItem* AddTail(AListItem* pItem) {return Cat(pItem);};
|
||||
AListItem* Remove(AListItem* pItem);
|
||||
AListItem* GetPrev(AListItem *pItem) const;
|
||||
AListItem* GetItem(LONG index);
|
||||
|
||||
private:
|
||||
AListItem *m_pNext;
|
||||
};
|
||||
|
||||
class AList
|
||||
{
|
||||
public:
|
||||
AList() {m_pHead=NULL;};
|
||||
AListItem *GetHead() const { return m_pHead;};
|
||||
|
||||
void RemoveAll() { m_pHead=NULL;};
|
||||
LONG GetCount() const {return m_pHead->GetCount();};
|
||||
AListItem *GetItem(LONG index) { return m_pHead->GetItem(index);};
|
||||
void InsertBefore(AListItem *pItem,AListItem *pInsert);
|
||||
void Cat(AListItem *pItem) {m_pHead=m_pHead->Cat(pItem);};
|
||||
void Cat(AList *pList)
|
||||
{
|
||||
// assert(pList!=NULL);
|
||||
m_pHead=m_pHead->Cat(pList->GetHead());
|
||||
};
|
||||
void AddHead(AListItem *pItem)
|
||||
{
|
||||
// assert(pItem!=NULL);
|
||||
pItem->SetNext(m_pHead);
|
||||
m_pHead=pItem;
|
||||
}
|
||||
void AddTail(AListItem *pItem);// {m_pHead=m_pHead->AddTail(pItem);};
|
||||
void Remove(AListItem *pItem) {m_pHead=m_pHead->Remove(pItem);};
|
||||
AListItem *GetPrev(AListItem *pItem) const {return m_pHead->GetPrev(pItem);};
|
||||
AListItem *GetTail() const {return GetPrev(NULL);};
|
||||
BOOL IsEmpty(void) const {return (m_pHead==NULL);};
|
||||
AListItem *RemoveHead(void)
|
||||
{
|
||||
AListItem *li;
|
||||
li=m_pHead;
|
||||
if(m_pHead)
|
||||
m_pHead=m_pHead->GetNext();
|
||||
// li->SetNext(NULL);
|
||||
return li;
|
||||
}
|
||||
void Reverse();
|
||||
|
||||
protected:
|
||||
AListItem *m_pHead;
|
||||
};
|
||||
|
||||
#endif // __ALIST_H__
|
||||
@@ -0,0 +1,575 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Param.cpp
|
||||
//
|
||||
// Desc: DirectShow sample code - definition of CParamsManager class.
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <medparam.h>
|
||||
#include "alist.h"
|
||||
#include "param.h"
|
||||
#include "dmerror.h"
|
||||
#include "param.h"
|
||||
#include "math.h"
|
||||
#include "validate.h"
|
||||
|
||||
// Disable some /W4 level warnings
|
||||
#pragma warning(disable:4296 4100 4505)
|
||||
|
||||
|
||||
CCurveList::~CCurveList()
|
||||
{
|
||||
while(this->GetHead())
|
||||
{
|
||||
delete this->RemoveHead();
|
||||
}
|
||||
}
|
||||
|
||||
CParamsManager::CParamsManager()
|
||||
|
||||
{
|
||||
m_fDirty = FALSE;
|
||||
m_cTimeFormats = 0;
|
||||
m_pguidTimeFormats = NULL;
|
||||
m_guidCurrentTimeFormat = GUID_NULL;
|
||||
m_cParams = 0;
|
||||
m_pCurveLists = NULL;
|
||||
m_pParamInfos = NULL;
|
||||
m_dwActiveBits = 0;
|
||||
InitializeCriticalSection(&m_ParamsCriticalSection);
|
||||
}
|
||||
|
||||
CParamsManager::~CParamsManager()
|
||||
{
|
||||
delete[] m_pguidTimeFormats;
|
||||
delete[] m_pCurveLists;
|
||||
delete[] m_pParamInfos;
|
||||
DeleteCriticalSection(&m_ParamsCriticalSection);
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::InitParams(DWORD cTimeFormats, const GUID *pguidTimeFormats, DWORD dwFormatIndex, MP_TIMEDATA mptdTimeData, DWORD cParams, ParamInfo *pParamInfo)
|
||||
{
|
||||
//check that the index is in a valid range
|
||||
if (0 > dwFormatIndex || dwFormatIndex >= cTimeFormats || cParams > sizeof(DWORD) * 8)
|
||||
return E_INVALIDARG;
|
||||
|
||||
m_pCurveLists = new CCurveList[cParams];
|
||||
if (!m_pCurveLists)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
// save the time formats
|
||||
m_pguidTimeFormats = new GUID[cTimeFormats];
|
||||
if (!m_pguidTimeFormats)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
for (DWORD dwIndex = 0; dwIndex < cTimeFormats; dwIndex++)
|
||||
{
|
||||
memcpy(&m_pguidTimeFormats[dwIndex], &pguidTimeFormats[dwIndex], sizeof(*pguidTimeFormats));
|
||||
}
|
||||
|
||||
// save the count of formats
|
||||
m_cTimeFormats = cTimeFormats;
|
||||
|
||||
// save the current time format
|
||||
m_guidCurrentTimeFormat = m_pguidTimeFormats[dwFormatIndex];
|
||||
|
||||
// save the TimeData
|
||||
m_mptdCurrentTimeData = mptdTimeData;
|
||||
|
||||
// save the parameter info
|
||||
m_pParamInfos
|
||||
= new ParamInfo[cParams];
|
||||
if (!m_pParamInfos)
|
||||
return E_OUTOFMEMORY;
|
||||
for (dwIndex = 0; dwIndex < cParams; dwIndex++)
|
||||
{
|
||||
if (pParamInfo[dwIndex].dwIndex < cParams)
|
||||
{
|
||||
memcpy(&m_pParamInfos[pParamInfo[dwIndex].dwIndex],&pParamInfo[dwIndex],sizeof(ParamInfo));
|
||||
}
|
||||
}
|
||||
m_cParams = cParams;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetParamCount(DWORD *pdwParams)
|
||||
|
||||
{
|
||||
if (pdwParams == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*pdwParams = m_cParams;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetParamInfo(DWORD dwParamIndex,MP_PARAMINFO *pInfo)
|
||||
|
||||
{
|
||||
if (!pInfo)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
if (dwParamIndex < m_cParams)
|
||||
{
|
||||
*pInfo = m_pParamInfos[dwParamIndex].MParamInfo;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetParamText(DWORD dwParamIndex,WCHAR **ppwchText)
|
||||
|
||||
{
|
||||
if (!ppwchText)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
if (dwParamIndex < m_cParams)
|
||||
{
|
||||
// write string of format: "Label\0Unit\0Enums1\0Enum2\0...EnumN\0\0"
|
||||
ParamInfo &pinfo = m_pParamInfos[dwParamIndex];
|
||||
int iUnit = wcslen(pinfo.MParamInfo.szLabel) + 1; // begin writing unit text here
|
||||
int iEnums = iUnit + wcslen(pinfo.MParamInfo.szUnitText) + 1; // begin writing enum text here
|
||||
int iEnd = iEnums + wcslen(pinfo.pwchText) + 1; // write the final (second) null terminator here
|
||||
WCHAR *pwsz = static_cast<WCHAR *>(CoTaskMemAlloc((iEnd + 1) * sizeof(WCHAR)));
|
||||
if (!pwsz)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
// wcscpy will write into various points of the string, neatly terminating each with a null
|
||||
wcscpy(pwsz, pinfo.MParamInfo.szLabel);
|
||||
wcscpy(pwsz + iUnit, pinfo.MParamInfo.szUnitText);
|
||||
wcscpy(pwsz + iEnums, pinfo.pwchText);
|
||||
|
||||
// The text field was defined with commas to separate the enum values.
|
||||
// Replace them with NULL characters now.
|
||||
for (WCHAR *pwch = pwsz + iEnums; *pwch; ++pwch)
|
||||
{
|
||||
if (*pwch == L',')
|
||||
*pwch = L'\0';
|
||||
}
|
||||
|
||||
pwsz[iEnd] = L'\0';
|
||||
|
||||
*ppwchText = pwsz;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetNumTimeFormats(DWORD *pdwNumTimeFormats)
|
||||
|
||||
{
|
||||
if (!pdwNumTimeFormats)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
*pdwNumTimeFormats = m_cTimeFormats;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetSupportedTimeFormat(DWORD dwFormatIndex,GUID *pguidTimeFormat)
|
||||
|
||||
{
|
||||
if (!pguidTimeFormat)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
if (dwFormatIndex >= m_cTimeFormats)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*pguidTimeFormat = m_pguidTimeFormats[dwFormatIndex];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetCurrentTimeFormat( GUID *pguidTimeFormat,MP_TIMEDATA *pTimeData)
|
||||
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
// Parameter Validation
|
||||
if ((pguidTimeFormat == NULL) || (pTimeData == NULL))
|
||||
{
|
||||
hr = E_POINTER;
|
||||
}
|
||||
|
||||
// Return the values
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*pguidTimeFormat = m_guidCurrentTimeFormat;
|
||||
*pTimeData = m_mptdCurrentTimeData;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CParamsManager::CopyParamsFromSource( CParamsManager * pSource)
|
||||
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
DWORD dwIndex;
|
||||
|
||||
for (dwIndex = 0; dwIndex < m_cTimeFormats; dwIndex++)
|
||||
{
|
||||
if (pSource->m_guidCurrentTimeFormat == m_pguidTimeFormats[dwIndex])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hr = InitParams(pSource->m_cTimeFormats, pSource->m_pguidTimeFormats, dwIndex, pSource->m_mptdCurrentTimeData, pSource->m_cParams,pSource->m_pParamInfos);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
for (dwIndex = 0; dwIndex < m_cParams; dwIndex++)
|
||||
{
|
||||
CCurveItem *pCurve = pSource->m_pCurveLists[dwIndex].GetHead();
|
||||
for (;pCurve;pCurve = pCurve->GetNext())
|
||||
{
|
||||
CCurveItem *pNew = new CCurveItem;
|
||||
if (!pNew)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
pNew->m_Envelope = pCurve->m_Envelope;
|
||||
m_pCurveLists[dwIndex].AddTail(pNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void
|
||||
CParamsManager ::UpdateActiveParams(REFERENCE_TIME rtTime, UpdateCallback &rThis)
|
||||
{
|
||||
if (!m_dwActiveBits)
|
||||
return; // nothing to recalc
|
||||
|
||||
DWORD dwBit = 1;
|
||||
for (DWORD dwIndex = 0; dwIndex < m_cParams; dwIndex++, dwBit = dwBit << 1)
|
||||
{
|
||||
if (m_dwActiveBits & dwBit)
|
||||
{
|
||||
float fVal = 0;
|
||||
HRESULT hr = GetParamFloat(dwIndex, rtTime, &fVal);
|
||||
rThis.SetParamUpdate(dwIndex, fVal);
|
||||
if (hr == S_FALSE)
|
||||
m_dwActiveBits &= ~dwBit; // we're beyond the last curve, don't need to recalc next time
|
||||
|
||||
//TraceI(6, "DMO value: time %I64d, param #%d, current value %hf\n", rtTime, dwIndex, fVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline float ValRange(float valToClip, float valMin, float valMax)
|
||||
{
|
||||
return valToClip < valMin
|
||||
? valMin
|
||||
: (valToClip > valMax ? valMax : valToClip);
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetParamFloat(DWORD dwParamIndex,REFERENCE_TIME rtTime,float *pval)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (dwParamIndex >= m_cParams)
|
||||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&m_ParamsCriticalSection);
|
||||
CCurveList *pList = &m_pCurveLists[dwParamIndex];
|
||||
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
|
||||
|
||||
// if no points, then neutral value
|
||||
CCurveItem *pCurveHead = pList->GetHead();
|
||||
if (!pCurveHead)
|
||||
{
|
||||
*pval = pInfo->MParamInfo.mpdNeutralValue;
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Find the curve during or before the requested time
|
||||
// If the time is during a curve, we will use that.
|
||||
// If not, we need the end value of the previous curve.
|
||||
// Our list keeps these in backwards order, so we are scanning from the
|
||||
// highest point in time backwards.
|
||||
|
||||
for (CCurveItem *pCurve = pCurveHead; pCurve && pCurve->m_Envelope.rtStart > rtTime;pCurve = pCurve->GetNext());
|
||||
|
||||
// If there is no pCurve, there was no curve prior to or during rtTime. Give up.
|
||||
if (!pCurve)
|
||||
{
|
||||
*pval = pInfo->MParamInfo.mpdNeutralValue;
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return S_OK;
|
||||
}
|
||||
// Now, if pCurve ends before the requested time,
|
||||
// return the final value of pCurve, since that will hold until the start of the next curve.
|
||||
if (pCurve->m_Envelope.rtEnd < rtTime)
|
||||
{
|
||||
*pval = pCurve->m_Envelope.valEnd;
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
if (pCurve == pCurveHead)
|
||||
return S_FALSE; // past last curve
|
||||
else
|
||||
return S_OK; // there are more curves ahead
|
||||
}
|
||||
|
||||
// If we get this far, the curve must bound rtTime.
|
||||
|
||||
if (pCurve->m_Envelope.iCurve & MP_CURVE_JUMP)
|
||||
{
|
||||
*pval = pCurve->m_Envelope.valEnd;
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
REFERENCE_TIME rtTimeChange = pCurve->m_Envelope.rtEnd - pCurve->m_Envelope.rtStart;
|
||||
REFERENCE_TIME rtTimeIntermediate = rtTime - pCurve->m_Envelope.rtStart;
|
||||
|
||||
float fltScalingX = static_cast<float>(rtTimeIntermediate) / rtTimeChange; // horizontal distance along curve between 0 and 1
|
||||
float fltScalingY; // height of curve at that point between 0 and 1 based on curve function
|
||||
switch (pCurve->m_Envelope.iCurve)
|
||||
{
|
||||
case MP_CURVE_SQUARE:
|
||||
fltScalingY = fltScalingX * fltScalingX;
|
||||
break;
|
||||
case MP_CURVE_INVSQUARE:
|
||||
fltScalingY = (float) sqrt(fltScalingX);
|
||||
break;
|
||||
case MP_CURVE_SINE:
|
||||
// <20><> Maybe we should have a lookup table here?
|
||||
fltScalingY = (float) (sin(fltScalingX * 3.1415926535 - (3.1415926535/2)) + 1) / 2;
|
||||
break;
|
||||
case MP_CURVE_LINEAR:
|
||||
default:
|
||||
fltScalingY = fltScalingX;
|
||||
}
|
||||
|
||||
// Find out if we need to pull the start point from the previous curve,
|
||||
// the default neutral value, or the current curve.
|
||||
float fStartVal = pCurve->m_Envelope.valStart;
|
||||
if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_NEUTRALVAL)
|
||||
{
|
||||
fStartVal = pInfo->MParamInfo.mpdNeutralValue;
|
||||
}
|
||||
// Currentval, if it exists, will override neutralval.
|
||||
if (pCurve->m_Envelope.flags & MPF_ENVLP_BEGIN_CURRENTVAL)
|
||||
{
|
||||
// Take advantage of the fact that these are inserted in backwards order.
|
||||
// Scan for the previous curve that ends before this time.
|
||||
CCurveItem *pPrevious = pCurve->GetNext();
|
||||
for (;pPrevious && pPrevious->m_Envelope.rtEnd > rtTime;pPrevious = pPrevious->GetNext());
|
||||
if (pPrevious)
|
||||
{
|
||||
fStartVal = pPrevious->m_Envelope.valEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply that scaling to the range of the actual points
|
||||
*pval = (pCurve->m_Envelope.valEnd - fStartVal) * fltScalingY + fStartVal;
|
||||
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::GetParamInt(DWORD dwParamIndex,REFERENCE_TIME rt,long *pval)
|
||||
|
||||
{
|
||||
HRESULT hr = E_POINTER;
|
||||
if (pval)
|
||||
{
|
||||
float fVal;
|
||||
hr = GetParamFloat(dwParamIndex,rt,&fVal);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*pval = (long) (fVal + 1/2); // Round.
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// IMediaParams
|
||||
|
||||
HRESULT CParamsManager::GetParam(DWORD dwParamIndex,MP_DATA *pValue)
|
||||
{
|
||||
V_INAME(CParams::GetParam);
|
||||
V_PTR_WRITE(pValue, MP_DATA);
|
||||
|
||||
if (dwParamIndex >= m_cParams)
|
||||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&m_ParamsCriticalSection);
|
||||
|
||||
CCurveList *pList = &m_pCurveLists[dwParamIndex];
|
||||
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
|
||||
// if no points, then neutral value
|
||||
CCurveItem *pCurve = pList->GetHead();
|
||||
if (pCurve)
|
||||
{
|
||||
*pValue = pCurve->m_Envelope.valEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pValue = pInfo->MParamInfo.mpdNeutralValue;
|
||||
}
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::SetParam(DWORD dwParamIndex,MP_DATA value)
|
||||
{
|
||||
V_INAME(CParams::SetParam);
|
||||
|
||||
if (dwParamIndex >= m_cParams)
|
||||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&m_ParamsCriticalSection);
|
||||
m_fDirty = TRUE;
|
||||
CCurveList *pList = &m_pCurveLists[dwParamIndex];
|
||||
// ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
|
||||
|
||||
// If we've already got a list, just force the most recent curve item to this value.
|
||||
// Otherwise, create a node and add it.
|
||||
CCurveItem *pCurve = pList->GetHead();
|
||||
if (!pCurve)
|
||||
{
|
||||
pCurve = new CCurveItem;
|
||||
if (pCurve)
|
||||
{
|
||||
pCurve->m_Envelope.rtStart = 0x8000000000000000; // Max negative.
|
||||
pCurve->m_Envelope.rtEnd = 0x7FFFFFFFFFFFFFFF; // Max positive.
|
||||
pCurve->m_Envelope.flags = 0;
|
||||
pList->AddHead(pCurve);
|
||||
}
|
||||
else
|
||||
{
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
pCurve->m_Envelope.valStart = value;
|
||||
pCurve->m_Envelope.valEnd = value;
|
||||
pCurve->m_Envelope.iCurve = MP_CURVE_JUMP;
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::AddEnvelope(
|
||||
DWORD dwParamIndex,
|
||||
DWORD cPoints,
|
||||
MP_ENVELOPE_SEGMENT *ppEnvelope)
|
||||
{
|
||||
V_INAME(CParams::AddEnvelope);
|
||||
V_PTR_READ(ppEnvelope, *ppEnvelope);
|
||||
|
||||
if (dwParamIndex >= m_cParams)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_pParamInfos)
|
||||
return DMUS_E_NOT_INIT;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
EnterCriticalSection(&m_ParamsCriticalSection);
|
||||
m_fDirty = TRUE;
|
||||
|
||||
CCurveList *pList = &m_pCurveLists[dwParamIndex];
|
||||
ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
|
||||
|
||||
DWORD dwCount;
|
||||
for (dwCount = 0; dwCount < cPoints; dwCount++)
|
||||
{
|
||||
CCurveItem *pCurve = new CCurveItem;
|
||||
if (!pCurve)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
pCurve->m_Envelope = ppEnvelope[dwCount];
|
||||
pCurve->m_Envelope.valEnd = ValRange(pCurve->m_Envelope.valEnd,
|
||||
pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);
|
||||
pCurve->m_Envelope.valStart = ValRange(pCurve->m_Envelope.valStart,
|
||||
pInfo->MParamInfo.mpdMinValue, pInfo->MParamInfo.mpdMaxValue);
|
||||
pList->AddHead(pCurve);
|
||||
m_dwActiveBits |= 1 << dwParamIndex; // next call to UpdateActiveParams will ensure the parameter's value is recalculated
|
||||
|
||||
//TraceI(6, "DMO envelope: time %I64d-%I64d, param #%d, value %hf-%hf\n",
|
||||
// pCurve->m_Envelope.rtStart, pCurve->m_Envelope.rtEnd,
|
||||
// dwParamIndex, pCurve->m_Envelope.valStart, pCurve->m_Envelope.valEnd);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::FlushEnvelope(
|
||||
DWORD dwParamIndex,
|
||||
REFERENCE_TIME refTimeStart,
|
||||
REFERENCE_TIME refTimeEnd)
|
||||
{
|
||||
if (dwParamIndex >= m_cParams)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_pParamInfos)
|
||||
return DMUS_E_NOT_INIT;
|
||||
|
||||
if (refTimeStart >= refTimeEnd)
|
||||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&m_ParamsCriticalSection);
|
||||
m_fDirty = TRUE;
|
||||
CCurveList *pList = &m_pCurveLists[dwParamIndex];
|
||||
// ParamInfo *pInfo = &m_pParamInfos[dwParamIndex];
|
||||
|
||||
CCurveList TempList;
|
||||
CCurveItem *pCurve;
|
||||
while ((pCurve = pList->RemoveHead()) != 0)
|
||||
{
|
||||
if ((pCurve->m_Envelope.rtStart >= refTimeStart) &&
|
||||
(pCurve->m_Envelope.rtEnd <= refTimeEnd))
|
||||
{
|
||||
delete pCurve;
|
||||
}
|
||||
else
|
||||
{
|
||||
TempList.AddHead(pCurve);
|
||||
}
|
||||
}
|
||||
while ((pCurve = TempList.RemoveHead()) != 0)
|
||||
{
|
||||
pList->AddHead(pCurve);
|
||||
}
|
||||
LeaveCriticalSection(&m_ParamsCriticalSection);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CParamsManager::SetTimeFormat(
|
||||
GUID guidTimeFormat,
|
||||
MP_TIMEDATA mpTimeData)
|
||||
{
|
||||
for (DWORD dwIndex = 0; dwIndex < m_cTimeFormats; dwIndex++)
|
||||
{
|
||||
if (guidTimeFormat == m_pguidTimeFormats[dwIndex])
|
||||
{
|
||||
m_guidCurrentTimeFormat = m_pguidTimeFormats[dwIndex];
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Param.h
|
||||
//
|
||||
// Desc: DirectShow sample code - definitions of CCurveItem, CCurveList,
|
||||
// and CParamsManager classes.
|
||||
//
|
||||
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __TOOLPARAM_H__
|
||||
#define __TOOLPARAM_H__
|
||||
|
||||
|
||||
|
||||
#include "medparam.h"
|
||||
#include "alist.h"
|
||||
|
||||
typedef struct _ParamInfo
|
||||
{
|
||||
DWORD dwIndex; // Which parameter.
|
||||
MP_PARAMINFO MParamInfo; // Standard MediaParams structure.
|
||||
WCHAR * pwchText; // Array of text names for enumerated types.
|
||||
} ParamInfo;
|
||||
|
||||
class CCurveItem : public AListItem
|
||||
{
|
||||
public:
|
||||
CCurveItem* GetNext() { return (CCurveItem*)AListItem::GetNext();}
|
||||
MP_ENVELOPE_SEGMENT m_Envelope; // Envelope segment.
|
||||
};
|
||||
|
||||
class CCurveList : public AList
|
||||
{
|
||||
public:
|
||||
// void Clear();
|
||||
void AddHead(CCurveItem* pCurveItem) { AList::AddHead((AListItem*)pCurveItem);}
|
||||
// void Insert(CCurveItem* pCurveItem);
|
||||
CCurveItem* GetHead(){return (CCurveItem*)AList::GetHead();}
|
||||
// CCurveItem* GetItem(LONG lIndex){return (CCurveItem*)AList::GetItem(lIndex);}
|
||||
CCurveItem* RemoveHead(){ return (CCurveItem*)AList::RemoveHead();}
|
||||
// void Remove(CCurveItem* pCurveItem){AList::Remove((AListItem*)pCurveItem);}
|
||||
// void AddTail(CCurveItem* pCurveItem){AList::AddTail((AListItem*)pCurveItem);}
|
||||
// CCurveItem* GetTail(){ return (CCurveItem*)AList::GetTail();}
|
||||
~CCurveList();
|
||||
};
|
||||
|
||||
#define MAX_REF_TIME 0x7FFFFFFFFFFFFFFF
|
||||
#define MP_CAPS_ALL MP_CAPS_CURVE_JUMP | MP_CAPS_CURVE_LINEAR | MP_CAPS_CURVE_SQUARE | MP_CAPS_CURVE_INVSQUARE | MP_CAPS_CURVE_SINE
|
||||
|
||||
class CParamsManager : public IMediaParams, public IMediaParamInfo
|
||||
{
|
||||
public:
|
||||
CParamsManager();
|
||||
~CParamsManager();
|
||||
|
||||
// IUnknown
|
||||
STDMETHOD(QueryInterface)(REFIID, LPVOID FAR *) PURE;
|
||||
STDMETHOD_(ULONG, AddRef)() PURE;
|
||||
STDMETHOD_(ULONG, Release)() PURE;
|
||||
|
||||
// IMediaParams
|
||||
STDMETHODIMP GetParam(DWORD dwParamIndex, MP_DATA *pValue);
|
||||
STDMETHODIMP SetParam(DWORD dwParamIndex,MP_DATA value);
|
||||
STDMETHODIMP AddEnvelope(DWORD dwParamIndex,DWORD cPoints,MP_ENVELOPE_SEGMENT *ppEnvelope);
|
||||
STDMETHODIMP FlushEnvelope( DWORD dwParamIndex,REFERENCE_TIME refTimeStart,REFERENCE_TIME refTimeEnd);
|
||||
STDMETHODIMP SetTimeFormat( GUID guidTimeFormat,MP_TIMEDATA mpTimeData);
|
||||
|
||||
// IMediaParamInfo
|
||||
STDMETHODIMP GetParamCount(DWORD *pdwParams);
|
||||
STDMETHODIMP GetParamInfo(DWORD dwParamIndex,MP_PARAMINFO *pInfo);
|
||||
STDMETHODIMP GetParamText(DWORD dwParamIndex,WCHAR **ppwchText);
|
||||
STDMETHODIMP GetNumTimeFormats(DWORD *pdwNumTimeFormats);
|
||||
STDMETHODIMP GetSupportedTimeFormat(DWORD dwFormatIndex,GUID *pguidTimeFormat);
|
||||
STDMETHODIMP GetCurrentTimeFormat( GUID *pguidTimeFormat,MP_TIMEDATA *pTimeData);
|
||||
|
||||
// other (non-COM) functions
|
||||
HRESULT InitParams(DWORD cTimeFormats, const GUID *pguidTimeFormats, DWORD dwFormatIndex, MP_TIMEDATA mptdTimeData, DWORD cParams, ParamInfo *pParamInfos);
|
||||
HRESULT GetParamFloat(DWORD dwParamIndex,REFERENCE_TIME rtTime,float *pval); // returns S_FALSE if rtTime is after the end time of the last curve
|
||||
HRESULT GetParamInt (DWORD dwParamIndex,REFERENCE_TIME rt,long *pval); // returns S_FALSE if rtTime is after the end time of the last curve
|
||||
HRESULT CopyParamsFromSource(CParamsManager * pSource);
|
||||
|
||||
// parameter control curve handling
|
||||
class UpdateCallback
|
||||
{
|
||||
public:
|
||||
// Define this in derived classes if you are going to use UpdateActiveParams.
|
||||
// Called by CParamsManager inside UpdateActiveParams to update the effect's internal state variables.
|
||||
// SetParamUpdate should be the same as SetParam, except that DMO defer the call to the base class
|
||||
// (CParamsManager::SetParam) in SetParam but should not do so in SetParamUpdate.
|
||||
virtual HRESULT SetParamUpdate(DWORD dwParamIndex, MP_DATA value) = 0;
|
||||
};
|
||||
// function that calls SetParam to adjust the value of all parameters that may have changed to their
|
||||
// new values at time rtTime
|
||||
void UpdateActiveParams(REFERENCE_TIME rtTime, UpdateCallback &rThis); // rThis should be the derived class (*this)
|
||||
DWORD GetActiveParamBits() { return m_dwActiveBits; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
|
||||
CRITICAL_SECTION m_ParamsCriticalSection;
|
||||
BOOL m_fDirty; // Has data changed since last file load or save?
|
||||
DWORD m_cTimeFormats; // Number of supported time formats.
|
||||
GUID *m_pguidTimeFormats; // Array of supported time formats.
|
||||
GUID m_guidCurrentTimeFormat; // The time format we're set to.
|
||||
MP_TIMEDATA m_mptdCurrentTimeData; // The unit of measure for the current time format.
|
||||
DWORD m_cParams; // Number of parameters.
|
||||
ParamInfo *m_pParamInfos; // Array of ParamInfo structures, one for each parameter.
|
||||
CCurveList *m_pCurveLists; // Array of Curve lists, one for each parameter.
|
||||
DWORD m_dwActiveBits; // Tracks the params that currently have curves active.
|
||||
};
|
||||
|
||||
#endif // __TOOLPARAM_H__
|
||||
@@ -0,0 +1,304 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: Validate.h
|
||||
//
|
||||
// Desc: DirectShow sample code - parameter validation macros.
|
||||
//
|
||||
// Copyright (c) 1997-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Summary:
|
||||
//
|
||||
// V_INAME(interfacename) - Set the interface name for error display
|
||||
// V_STRUCTPTR_READ(ptr,type) - A dwSize struct which we will read
|
||||
// V_STRUCTPTR_WRITE(ptr,type) - A dwSize struct which we will read/write
|
||||
// V_PTR_READ(ptr,type) - A typed ptr w/o a dwSize which we will read
|
||||
// V_PTR_WRITE(ptr,type) - A typed ptr w/o a dwSize which we will read/write
|
||||
// V_PTR_WRITE_OPT(ptr,type) - An optional typed ptr w/o a dwSize which we will read/write
|
||||
// V_BUFPTR_READ(ptr,size) - A variable-size buffer that we will read
|
||||
// V_BUFPTR_READ_OPT(ptr,size) - An optional variable-size buffer that we will read
|
||||
// V_BUFPTR_WRITE(ptr,size) - A variable-size buffer that we will read/write
|
||||
// V_BUFPTR_WRITE_OPT(ptr,size) - An optional variable-size buffer that we will read/write
|
||||
// V_PTRPTR_WRITE(ptrptr) - A pointer to a pointer to write to
|
||||
// V_PTRPTR_WRITE_OPT(ptrptr) - A pointer to a pointer to write to that is optional
|
||||
// V_PUNKOUTER(punk) - A pointer to a controlling unknown, aggregation supported
|
||||
// V_PUNKOUTER_NOADD(punk) - A pointer to a controlling unknown, aggregation not supported
|
||||
// V_INTERFACE(ptr) - A pointer to a COM interface
|
||||
// V_INTERFACE_OPT(ptr) - An optional pointer to a COM interface
|
||||
// V_REFGUID(ref) - A reference to a GUID (type REFGUID)
|
||||
// V_HWND(hwnd) - A window handle
|
||||
// V_HWNDOPT(hwnd) - An optional window handle
|
||||
//
|
||||
// For handling different versions of structures:
|
||||
//
|
||||
// V_STRUCTPTR_READ_VER(ptr,ver) - Begin a struct version block for read access
|
||||
// At the end, 'ver' will contain the
|
||||
// discovered version of the struct
|
||||
// V_STRUCTPTR_READ_VER_CASE(base,ver) - Test struct against version ver of
|
||||
// type 'base'.
|
||||
// V_STRUCTPTR_READ_VER_END(base,ptr) - End a struct version block
|
||||
//
|
||||
// V_STRUCTPTR_WRITE_VER(ptr,ver) - Struct version block for write access
|
||||
// V_STRUCTPTR_WRITE_VER_CASE(base,ver)
|
||||
// V_STRUCTPTR_WRITE_VER_END(base,ptr)
|
||||
//
|
||||
// The struct version block expects type names of a base type followed by a
|
||||
// numeric version, such as
|
||||
//
|
||||
// typedef struct { } FOO7;
|
||||
// typedef struct { } FOO8;
|
||||
//
|
||||
// In the header FOO and LPFOO are conditionally typedef'd based on a version
|
||||
// #define. The DLL will be compiled with the latest version number and hence
|
||||
// the largest version of the struct.
|
||||
//
|
||||
// Since Windows headers are compiled by default with 8-byte alignment, adding
|
||||
// one DWORD may not cause the size of the structure to change. If this happens
|
||||
// you will get a 'case label already used' error on one of the VER_CASE macros.
|
||||
// If this happens, you can get around it by adding a dwReserved field to the
|
||||
// end of the struct to force the padding.
|
||||
//
|
||||
// 'optional' means the pointer is allowed to be NULL by the interface specification.
|
||||
//
|
||||
// Sample usage:
|
||||
//
|
||||
// int IDirectMusic::SetFooBarInterface(
|
||||
// LPDMUS_REQUESTED_CAPS pCaps, // Caps w/ dwSize (read-only)
|
||||
// LPVOID pBuffer, // Buffer we will fill in
|
||||
// DWORD cbSize, // Size of the buffer
|
||||
// PDIRECTMUSICBAR pBar) // Callback interface for bar on this buffer
|
||||
// {
|
||||
// V_INTERFACE(IDirectMusic::SetFooBarInterface);
|
||||
// V_BUFPTR_WRITE(pBuffer, cbSize);
|
||||
// V_INTERFACE(pBar);
|
||||
// DWORD dwCapsVer; // Must be a DWORD!!!
|
||||
//
|
||||
// V_STRUCTPTR_READ_VER(pCaps, dwCapsVer);
|
||||
// V_STRUCTPTR_READ_VER_CASE(DMUS_REQUESTED_CAPS, 7);
|
||||
// V_STRUCTPTR_READ_VER_CASE(DMUS_REQUESTED_CAPS, 8);
|
||||
// V_STRUCTPTR_READ_VER_END_(DMUS_REQUESTED_CAPS, pCaps);
|
||||
//
|
||||
// // At this point, if we are still in the function we have a valid pCaps
|
||||
// // pointer and dwCapsVer is either 7 or 8, indicating the version of
|
||||
// // the struct passed in.
|
||||
//
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
#ifndef _VALIDATE_H_
|
||||
#define _VALIDATE_H_
|
||||
|
||||
|
||||
#ifdef DBG
|
||||
#include <stddef.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
// To turn on DebugBreak on parameter error, use the following or -DRIP_BREAK in the build:
|
||||
//
|
||||
//#define RIP_BREAK 1
|
||||
|
||||
#ifdef RIP_BREAK
|
||||
#define _RIP_BREAK DebugBreak();
|
||||
#else
|
||||
#define _RIP_BREAK
|
||||
#endif
|
||||
|
||||
#define V_INAME(x) \
|
||||
static const char __szValidateInterfaceName[] = #x;
|
||||
|
||||
#define RIP_E_POINTER(ptr) \
|
||||
{ Trace(-1, "%s: Invalid pointer " #ptr "\n", __szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
return E_POINTER; }
|
||||
|
||||
#define RIP_E_INVALIDARG(ptr) \
|
||||
{ Trace(-1, "%s: Invalid argument " #ptr "\n", __szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
return E_INVALIDARG; }
|
||||
|
||||
#define RIP_E_HANDLE(h) \
|
||||
{ Trace(-1, "%s: Invalid handle " #h "\n", __szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
return E_HANDLE; }
|
||||
|
||||
#define RIP_W_INVALIDSIZE(ptr) \
|
||||
{ Trace(-1, "%s: " #ptr "->dwSize matches no known structure size. Defaulting to oldest structure.\n", \
|
||||
__szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
}
|
||||
|
||||
#define RIP_E_INVALIDSIZE(ptr) \
|
||||
{ Trace(-1, "%s: " #ptr "->dwSize is too small\n", __szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
return E_INVALIDARG; }
|
||||
|
||||
#define RIP_E_BLOCKVSDWSIZE(ptr) \
|
||||
{ Trace(-1, "%s: " #ptr " does not point to as much memory as " #ptr "->dwSize indicates\n", \
|
||||
__szValidateInterfaceName); \
|
||||
_RIP_BREAK \
|
||||
return E_INVALIDARG; }
|
||||
|
||||
// NOTE: The DebugBreak() not in #ifdef is intentional - this is something that
|
||||
// must be fixed in our code, not an app-generated error.
|
||||
//
|
||||
#define V_ASSERT(exp) \
|
||||
{ if (!(exp)) { \
|
||||
Trace(-1, "%s@%s: %s\n", __FILE__, __LINE__, #exp); \
|
||||
DebugBreak(); }}
|
||||
|
||||
#else
|
||||
|
||||
#define V_INAME(x)
|
||||
#define RIP_E_POINTER(ptr) { return E_POINTER; }
|
||||
#define RIP_E_INVALIDARG(ptr) { return E_INVALIDARG; }
|
||||
#define RIP_E_HANDLE(h) { return E_HANDLE; }
|
||||
#define RIP_E_BLOCKVSDWSIZE(ptr) { return E_INVALIDARG; }
|
||||
#define RIP_W_INVALIDSIZE(ptr)
|
||||
#define RIP_E_INVALIDSIZE(ptr) { return E_INVALIDARG; }
|
||||
#define V_ASSERT(exp)
|
||||
|
||||
#endif // DBG
|
||||
|
||||
// A passed struct we will only read from or may write to. Must be a struct
|
||||
// with a dwSize.
|
||||
//
|
||||
// int foo(CFoo *pFoo)
|
||||
// ...
|
||||
// V_STRUCTPTR_READ(pFoo, CFoo);
|
||||
// V_STRUCTPTR_WRITE(pFoo, CFoo);
|
||||
//
|
||||
// Use _PTR_ variants for structs w/o a dwSize
|
||||
//
|
||||
#define V_STRUCTPTR_READ(ptr,type) \
|
||||
{ V_ASSERT(offsetof(type, dwSize) == 0); \
|
||||
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
if (ptr->dwSize < sizeof(type)) RIP_E_INVALIDSIZE(ptr); \
|
||||
if (IsBadReadPtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); }
|
||||
|
||||
#define V_STRUCTPTR_WRITE(ptr,type) \
|
||||
{ V_ASSERT(offsetof(type, dwSize) == 0); \
|
||||
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
if (ptr->dwSize < sizeof(type)) RIP_E_INVALIDSIZE(ptr); \
|
||||
if (IsBadWritePtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); }
|
||||
|
||||
#define V_PTR_READ(ptr,type) \
|
||||
{ if (IsBadReadPtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_PTR_WRITE(ptr,type) \
|
||||
{ if (IsBadWritePtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_PTR_WRITE_OPT(ptr,type) \
|
||||
{ if (ptr) if (IsBadWritePtr(ptr, sizeof(type))) RIP_E_POINTER(ptr); }
|
||||
|
||||
// A buffer pointer with separate length (not defined by the pointer type) we will only
|
||||
// read from or may write to.
|
||||
//
|
||||
// int foo(LPVOID *pBuffer, DWORD cbBuffer)
|
||||
// ...
|
||||
// V_BUFPTR_READ(pBuffer, cbBuffer);
|
||||
// V_BUFPTR_WRITE(pBuffer, cbBuffer);
|
||||
//
|
||||
#define V_BUFPTR_READ(ptr,len) \
|
||||
{ if (IsBadReadPtr(ptr, len)) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_BUFPTR_READ_OPT(ptr,len) \
|
||||
{ if (ptr) V_BUFPTR_READ(ptr,len); }
|
||||
|
||||
#define V_BUFPTR_WRITE(ptr,len) \
|
||||
{ if (IsBadWritePtr(ptr, len)) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_BUFPTR_WRITE_OPT(ptr,len) \
|
||||
{ if (ptr) V_BUFPTR_WRITE(ptr,len); }
|
||||
|
||||
// A pointer to a pointer (such as a pointer to an interface pointer) to return
|
||||
//
|
||||
// int foo(IReturnMe **ppRet)
|
||||
// ...
|
||||
// V_PTRPTR_WRITE(ppRet);
|
||||
// V_PTRPTR_WRITE_OPT(ppRet);
|
||||
//
|
||||
#define V_PTRPTR_WRITE(ptr) \
|
||||
{ if (IsBadWritePtr(ptr, sizeof(void*))) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_PTRPTR_WRITE_OPT(ptr) \
|
||||
{ if (ptr) if (IsBadWritePtr(ptr, sizeof(void*))) RIP_E_POINTER(ptr); }
|
||||
|
||||
// A pointer to a controlling unknown
|
||||
//
|
||||
#define V_PUNKOUTER(punk) \
|
||||
{ if (punk && IsBadCodePtr(punk)) RIP_E_POINTER(ptr); }
|
||||
|
||||
// A pointer to a controlling unknown for which we don't support aggregation
|
||||
//
|
||||
#define V_PUNKOUTER_NOAGG(punk) \
|
||||
{ if (punk && IsBadReadPtr(punk, sizeof(IUnknown))) RIP_E_POINTER(ptr); \
|
||||
if (punk) return CLASS_E_NOAGGREGATION; }
|
||||
|
||||
// Validate an incoming interface pointer.
|
||||
//
|
||||
struct _V_GENERIC_INTERFACE
|
||||
{
|
||||
FARPROC *(__vptr[1]);
|
||||
};
|
||||
|
||||
#define V_INTERFACE(ptr) \
|
||||
{ if (IsBadReadPtr(ptr, sizeof(_V_GENERIC_INTERFACE))) RIP_E_POINTER(ptr); \
|
||||
if (IsBadReadPtr(*reinterpret_cast<_V_GENERIC_INTERFACE*>(ptr)->__vptr, sizeof(FARPROC))) \
|
||||
RIP_E_POINTER(ptr); \
|
||||
if (IsBadCodePtr(*(reinterpret_cast<_V_GENERIC_INTERFACE*>(ptr)->__vptr)[0])) RIP_E_POINTER(ptr); }
|
||||
|
||||
#define V_INTERFACE_OPT(ptr) \
|
||||
{ if (ptr) V_INTERFACE(ptr); }
|
||||
|
||||
// Validation for a reference to a GUID, which we only ever read.
|
||||
//
|
||||
#define V_REFGUID(ref) \
|
||||
{ if (IsBadReadPtr((void*)&ref, sizeof(GUID))) RIP_E_POINTER((void*)&ref); }
|
||||
|
||||
// Validation for a window handle
|
||||
//
|
||||
#define V_HWND(h) \
|
||||
{ if (!IsWindow(h)) RIP_E_HANDLE(h); }
|
||||
|
||||
#define V_HWND_OPT(h) \
|
||||
{ if (h) if (!IsWindow(h)) RIP_E_HANDLE(h); }
|
||||
|
||||
// Validation for multiple sized structs based on version
|
||||
//
|
||||
#define V_STRUCTPTR_READ_VER(ptr,ver) \
|
||||
{ ver = 7; DWORD *pdw = &ver; \
|
||||
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
if (IsBadReadPtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
switch ((ptr)->dwSize) {
|
||||
|
||||
#define V_STRUCTPTR_READ_VER_CASE(basetype,ver) \
|
||||
case sizeof(basetype##ver) : \
|
||||
V_ASSERT(offsetof(basetype##ver, dwSize) == 0); \
|
||||
*pdw = ver; break;
|
||||
|
||||
#define V_STRUCTPTR_READ_VER_END(basetype,ptr) \
|
||||
default : if ((ptr)->dwSize > sizeof(basetype##7)) \
|
||||
{ RIP_W_INVALIDSIZE(ptr); } else \
|
||||
RIP_E_INVALIDSIZE(ptr); }}
|
||||
|
||||
|
||||
#define V_STRUCTPTR_WRITE_VER(ptr,ver) \
|
||||
{ ver = 7; DWORD *pdw = &ver; \
|
||||
if (IsBadReadPtr(ptr, sizeof(DWORD))) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
if (IsBadWritePtr(ptr, (ptr)->dwSize)) RIP_E_BLOCKVSDWSIZE(ptr); \
|
||||
switch ((ptr)->dwSize) {
|
||||
|
||||
#define V_STRUCTPTR_WRITE_VER_CASE(basetype,ver) \
|
||||
case sizeof(basetype##ver) : \
|
||||
V_ASSERT(offsetof(basetype##ver, dwSize) == 0); \
|
||||
*pdw = ver; break;
|
||||
|
||||
#define V_STRUCTPTR_WRITE_VER_END(basetype,ptr) \
|
||||
default : if ((ptr)->dwSize > sizeof(basetype##7)) \
|
||||
{ RIP_W_INVALIDSIZE(ptr); } else \
|
||||
RIP_E_INVALIDSIZE(ptr); }}
|
||||
|
||||
|
||||
|
||||
#endif // _VALIDATE_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by GargleDMO.rc
|
||||
//
|
||||
#define IDS_PROJNAME 100
|
||||
#define IDR_GARGLE 101
|
||||
#define IDR_GARGPROP 102
|
||||
#define IDS_TITLEGargDMOProp 103
|
||||
#define IDS_HELPFILEGargDMOProp 104
|
||||
#define IDS_DOCSTRINGGargDMOProp 105
|
||||
#define IDR_GARGDMOPROP 106
|
||||
#define IDD_GARGDMOPROP 107
|
||||
|
||||
#define IDC_RADIO_SIN 205
|
||||
#define IDC_RADIO_TRIANGLE 206
|
||||
#define IDC_RADIO_SQUARE 224
|
||||
#define IDC_EDIT_Rate 222
|
||||
#define IDC_SLIDER_Rate 223
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 201
|
||||
#define _APS_NEXT_COMMAND_VALUE 32768
|
||||
#define _APS_NEXT_CONTROL_VALUE 201
|
||||
#define _APS_NEXT_SYMED_VALUE 108
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// stdafx.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _ATL_STATIC_REGISTRY
|
||||
#include <statreg.h>
|
||||
#include <statreg.cpp>
|
||||
#endif
|
||||
|
||||
#include <atlimpl.cpp>
|
||||
@@ -0,0 +1,30 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__492E5415_2B6C_4CAF_A7F5_E9D1177404AC__INCLUDED_)
|
||||
#define AFX_STDAFX_H__492E5415_2B6C_4CAF_A7F5_E9D1177404AC__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define STRICT
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#define _ATL_APARTMENT_THREADED
|
||||
|
||||
#include <atlbase.h>
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
#include <atlctl.h>
|
||||
|
||||
#pragma warning(disable:4100) // C4100: unreferenced formal parameter
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__492E5415_2B6C_4CAF_A7F5_E9D1177404AC__INCLUDED)
|
||||
@@ -0,0 +1,59 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// File: IGargle.h
|
||||
//
|
||||
// Desc: DirectShow sample code - custom interface to allow the user
|
||||
// to adjust the modulation rate. It defines the interface between
|
||||
// the user interface component (the property sheet) and the filter
|
||||
// itself. This interface is exported by the code in Gargle.cpp and
|
||||
// is used by the code in GargProp.cpp.
|
||||
//
|
||||
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __IGARGLEDMO__
|
||||
#define __IGARGLEDMO__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// IGargleDMOSample's GUID
|
||||
//
|
||||
// {9AE9B11C-4EF8-42bc-9484-65EA0008964F}
|
||||
DEFINE_GUID(IID_IGargleDMOSample,
|
||||
0x9ae9b11c, 0x4ef8, 0x42bc, 0x94, 0x84, 0x65, 0xea, 0x0, 0x8, 0x96, 0x4f);
|
||||
|
||||
typedef struct _GargleFX
|
||||
{
|
||||
DWORD dwRateHz; // Rate of modulation in hz
|
||||
DWORD dwWaveShape; // GARGLE_FX_WAVE_xxx
|
||||
} GargleFX, *LPGargleFX;
|
||||
|
||||
#define GARGLE_FX_WAVE_TRIANGLE 0
|
||||
#define GARGLE_FX_WAVE_SQUARE 1
|
||||
|
||||
typedef const GargleFX *LPCGargleFX;
|
||||
|
||||
#define GARGLE_FX_RATEHZ_MIN 1
|
||||
#define GARGLE_FX_RATEHZ_MAX 1000
|
||||
|
||||
//
|
||||
// IGargleDMOSample
|
||||
//
|
||||
DECLARE_INTERFACE_(IGargleDMOSample, IUnknown) {
|
||||
|
||||
// IGargleDMOSample methods
|
||||
STDMETHOD(SetAllParameters) (THIS_ LPCGargleFX pcGargleFx) PURE;
|
||||
STDMETHOD(GetAllParameters) (THIS_ LPGargleFX pGargleFx) PURE;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __IGARGLEDMO__
|
||||
@@ -0,0 +1,41 @@
|
||||
DirectShow Sample -- GargleDMO
|
||||
------------------------------
|
||||
|
||||
Description
|
||||
|
||||
This sample is a Microsoft DirectX Media Object (DMO) that creates a
|
||||
gargle effect, similar to the Gargle Filter sample for Microsoft DirectShow.
|
||||
|
||||
This sample demonstrates how to implement the the following interfaces:
|
||||
|
||||
IMediaObject
|
||||
IMediaObjectInPlace
|
||||
IMediaParamInfo
|
||||
IMediaParams
|
||||
|
||||
|
||||
User's Guide
|
||||
|
||||
To use this DMO, build and register GargleDMO.dll. The sample project builds
|
||||
several intermediate libraries. To build the DLL in Microsoft Visual Studio,
|
||||
select Batch Build from the Build menu.
|
||||
|
||||
You can use the DMO in the DMO Demo sample application, or with the
|
||||
DirectShow GraphEdit utility. GraphEdit automatically wraps the DMO in the
|
||||
DMO Wrapper filter.
|
||||
|
||||
You can also use the DMO in Microsoft DirectMusic applications, including
|
||||
the Microsoft DirectMusic Producer application included with the SDK.
|
||||
In DirectMusic Producer, use the Audiopath Designer to insert the DMO into an
|
||||
audiopath. To control media parameters, use the Parameter Control track.
|
||||
Insert a curve in the track and assign it to control any of the properties
|
||||
on the DMO. For more information, see the Audiopath Designer and Parameter
|
||||
Control Track topics in the DirectMusic Producer application help.
|
||||
|
||||
The Gargle DMO provides a property page for the user to set the shape of the
|
||||
modulating waveform (square or triangular) and the frequency. It also supports
|
||||
a custom interface, IGargleDMOSample, for setting these properties.
|
||||
|
||||
|
||||
For more information about this sample, see "DirectShow Samples" in the
|
||||
DirectX 8 SDK documentation.
|
||||
Reference in New Issue
Block a user