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