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:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View 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);
}

View File

@@ -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

View File

@@ -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_

View File

@@ -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'
}
}
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -0,0 +1,9 @@
; dmosample.def : Declares the module parameters.
LIBRARY "dmosample.DLL"
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

View File

@@ -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>

View File

@@ -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.

View File

@@ -0,0 +1,3 @@
#define IDR_SAMPLE 101

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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();
};

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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_

View File

@@ -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'
}
}
}
}

View File

@@ -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(&params);
if (SUCCEEDED(hr))
hr = pNewGargle->SetAllParameters(&params);
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);
}

View File

@@ -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_

View File

@@ -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'
}
}
}
}

View File

@@ -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);
}

View File

@@ -0,0 +1,9 @@
; GargleDMO.def : Declares the module parameters.
LIBRARY "GargleDMO.DLL"
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

View File

@@ -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

View File

@@ -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>
{{{
}}}
###############################################################################

View File

@@ -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

View File

@@ -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
/////////////////////////////////////////////////////////////////////////////

View File

@@ -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

View File

@@ -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());
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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_

View File

@@ -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

View File

@@ -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>

View File

@@ -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)

View File

@@ -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__

View File

@@ -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.