mirror of
https://github.com/electronicarts/CnC_Generals_Zero_Hour
synced 2025-08-16 22:25:04 +02:00
Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
150
Generals/Code/Libraries/Source/WPAudio/AUD_Assert.cpp
Normal file
150
Generals/Code/Libraries/Source/WPAudio/AUD_Assert.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audassrt.cpp **
|
||||
** **
|
||||
** Created by: 12/??/00 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
//#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
extern void WindowsDebugPrint( const char * lpOutputString );
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
char *DBG_type_struct_is_dead = "Invalid structure";
|
||||
char assert_msg_buf[10*1024];
|
||||
static FILE *err_file = NULL;
|
||||
static int total_errors;
|
||||
static char _msg_buf[sizeof(assert_msg_buf)*2];
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef _DEBUG
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void __cdecl _assert_printf ( const char *format, ...)
|
||||
{
|
||||
|
||||
va_list args;
|
||||
va_start( args, format ); /* Initialize variable arguments. */
|
||||
|
||||
vsprintf ( assert_msg_buf, format, args );
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void __cdecl _aud_debug_printf ( const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start( args, format ); /* Initialize variable arguments. */
|
||||
|
||||
vsprintf ( _msg_buf, format, args );
|
||||
va_end( args );
|
||||
|
||||
WindowsDebugPrint ( _msg_buf );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void _aud_assert ( const char *, const char *file, int line, const char *reason )
|
||||
{
|
||||
sprintf ( _msg_buf, "%s(%d) : Error : ASSERT - %s\n", file, line, reason );
|
||||
WindowsDebugPrint ( _msg_buf );
|
||||
_assert ( _msg_buf, (void *) file, line );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
230
Generals/Code/Libraries/Source/WPAudio/AUD_Attributes.cpp
Normal file
230
Generals/Code/Libraries/Source/WPAudio/AUD_Attributes.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audattr.cpp **
|
||||
** **
|
||||
** Created by: 11/16/95 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/level.h>
|
||||
#include <wpaudio/attributes.h>
|
||||
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioAttribs )
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioAttribsInit ( AudioAttribs *attr )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( attr != NULL);
|
||||
DBG_SET_TYPE ( attr, AudioAttribs );
|
||||
|
||||
AudioLevelInit ( &attr->VolumeLevel, AUDIO_VOLUME_MAX );
|
||||
AudioLevelInit ( &attr->PitchLevel, 100);
|
||||
AudioLevelInit ( &attr->PanPosition, AUDIO_PAN_CENTER);
|
||||
AudioAttribsSetPitchDuration (attr, SECONDS(1), 10 );
|
||||
AudioAttribsSetVolumeDuration (attr, SECONDS(1), AUDIO_LEVEL_MAX );
|
||||
AudioAttribsSetPanDuration (attr, SECONDS(1), AUDIO_LEVEL_MAX );
|
||||
|
||||
AudioLevelSet ( &attr->VolumeLevel, AUDIO_VOLUME_MAX );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioAttribsUpdate ( AudioAttribs *attr )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( attr, AudioAttribs );
|
||||
|
||||
AudioLevelUpdate ( &attr->VolumeLevel );
|
||||
AudioLevelUpdate ( &attr->PitchLevel );
|
||||
AudioLevelUpdate ( &attr->PanPosition );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioAttribsChanged ( AudioAttribs *attr )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( attr, AudioAttribs );
|
||||
|
||||
return AudioLevelChanged ( &attr->VolumeLevel ) || AudioLevelChanged ( &attr->PitchLevel ) || AudioLevelChanged ( &attr->PanPosition );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioAttribsApply ( AudioAttribs *attr, AudioAttribs *mod )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( attr, AudioAttribs );
|
||||
DBG_ASSERT_TYPE ( mod, AudioAttribs );
|
||||
|
||||
|
||||
AudioLevelSet ( &attr->VolumeLevel, AudioLevelApply ( &mod->VolumeLevel, AudioAttribsGetVolume ( attr ) ));
|
||||
AudioLevelUpdate ( &attr->VolumeLevel );
|
||||
|
||||
{
|
||||
// apply pitch
|
||||
int level;
|
||||
int change;
|
||||
|
||||
|
||||
level = AudioAttribsGetPitch ( attr );
|
||||
change = AudioAttribsGetPitch ( mod );
|
||||
|
||||
|
||||
level = (level * change) / 100;
|
||||
|
||||
AudioAttribsSetPitch ( attr, level );
|
||||
AudioLevelUpdate ( &attr->PitchLevel );
|
||||
}
|
||||
|
||||
{
|
||||
// apply pan
|
||||
int pos;
|
||||
|
||||
if ( (pos = AudioAttribsGetPan ( mod ) - AUDIO_PAN_CENTER) != 0 )
|
||||
{
|
||||
if ( ( pos = pos + AudioAttribsGetPan ( attr )) < AUDIO_PAN_LEFT )
|
||||
{
|
||||
pos = AUDIO_PAN_LEFT ;
|
||||
}
|
||||
else if ( pos > AUDIO_PAN_RIGHT )
|
||||
{
|
||||
pos = AUDIO_PAN_RIGHT ;
|
||||
}
|
||||
|
||||
AudioAttribsSetPan ( attr, pos );
|
||||
}
|
||||
AudioLevelUpdate ( &attr->PanPosition );
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioAttribsUsed ( AudioAttribs *attr )
|
||||
{
|
||||
AudioLevelUsed ( &attr->VolumeLevel );
|
||||
AudioLevelUsed ( &attr->PanPosition );
|
||||
AudioLevelUsed ( &attr->PitchLevel );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioAttribsCalcPitch ( AudioAttribs *attr, int pitch )
|
||||
{
|
||||
int level;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( attr, AudioAttribs );
|
||||
|
||||
level = AudioAttribsGetPitch ( attr );
|
||||
|
||||
return ( pitch * level ) / 100;
|
||||
|
||||
}
|
||||
|
586
Generals/Code/Libraries/Source/WPAudio/AUD_Cache.cpp
Normal file
586
Generals/Code/Libraries/Source/WPAudio/AUD_Cache.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audcache.cpp **
|
||||
** **
|
||||
** Created by: 04/30/99 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <wpaudio/altypes.h> // always include this header first
|
||||
#include <wpaudio/memory.h>
|
||||
#include <wpaudio/list.h>
|
||||
#include <wpaudio/source.h>
|
||||
#include <wpaudio/cache.h>
|
||||
#include <wpaudio/profiler.h>
|
||||
|
||||
#include <wsys/File.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioCache );
|
||||
DBG_DECLARE_TYPE ( AudioCacheItem );
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
#define DEBUG_CACHE 0
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static void audioCacheAssetClose ( AudioCache *cache )
|
||||
{
|
||||
if ( cache->assetFile )
|
||||
{
|
||||
cache->assetFile->close();
|
||||
cache->assetFile = NULL;
|
||||
}
|
||||
|
||||
cache->assetBytesLeft = 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static int audioCacheAssetOpen ( AudioCache *cache, const char *name )
|
||||
{
|
||||
audioCacheAssetClose ( cache );
|
||||
|
||||
if ( name == NULL || cache->openAssetCB == NULL )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cache->assetFile = cache->openAssetCB( name );
|
||||
|
||||
if ( !cache->assetFile )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !AudioFormatReadWaveFile ( cache->assetFile, &cache->assetFormat, &cache->assetBytesLeft ))
|
||||
{
|
||||
audioCacheAssetClose ( cache );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int audioCacheAssetRead ( AudioCache *cache, void *data, int bytes )
|
||||
{
|
||||
if ( bytes > cache->assetBytesLeft )
|
||||
{
|
||||
bytes = cache->assetBytesLeft;
|
||||
}
|
||||
|
||||
return cache->assetFile ? cache->assetFile->read ( data, bytes ) : 0 ;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioCache* AudioCacheCreate ( int cacheSize, int maxItems, int frameSize )
|
||||
{
|
||||
AudioCache *cache;
|
||||
int frameBytes;
|
||||
int pages;
|
||||
|
||||
ALLOC_STRUCT ( cache, AudioCache );
|
||||
|
||||
DBG_SET_TYPE ( cache, AudioCache );
|
||||
|
||||
cache->frameSize = frameSize;
|
||||
|
||||
frameBytes = sizeof ( AudioFrame ) + frameSize;
|
||||
pages = cacheSize/frameBytes;
|
||||
|
||||
cache->framePool = MemoryPoolCreate ( pages, frameBytes );
|
||||
|
||||
cache->itemPool = MemoryPoolCreate ( maxItems, sizeof ( AudioCacheItem ) );
|
||||
|
||||
ListInit ( &cache->items );
|
||||
cache->assetFile = NULL;
|
||||
AudioFormatInit ( &cache->assetFormat );
|
||||
|
||||
ProfCacheInit ( &cache->profile, pages, frameSize );
|
||||
ProfCacheUpdateInterval ( &cache->profile, 10 ); // every ten milliseconds
|
||||
|
||||
if ( !cache->framePool || !cache->itemPool )
|
||||
{
|
||||
AudioCacheDestroy ( cache );
|
||||
cache = NULL;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioCacheDestroy ( AudioCache *cache )
|
||||
{
|
||||
AudioCacheItem *item;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( cache, AudioCache );
|
||||
|
||||
while ( ( item = (AudioCacheItem *) ListNodeNext ( &cache->items )) )
|
||||
{
|
||||
AudioCacheItemFree ( item );
|
||||
}
|
||||
|
||||
if ( cache->framePool )
|
||||
{
|
||||
MemoryPoolDestroy ( cache->framePool );
|
||||
}
|
||||
|
||||
if ( cache->itemPool )
|
||||
{
|
||||
MemoryPoolDestroy ( cache->itemPool );
|
||||
}
|
||||
|
||||
DBG_INVALIDATE_TYPE ( cache );
|
||||
|
||||
AudioMemFree ( cache );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioCacheItem* AudioCacheGetItem ( AudioCache *cache, const char *name )
|
||||
{
|
||||
AudioCacheItem *item, *head;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( cache, AudioCache );
|
||||
|
||||
item = head = (AudioCacheItem *) &cache->items ;
|
||||
|
||||
while ( (item = (AudioCacheItem *) item->nd.next ) != head )
|
||||
{
|
||||
if ( item->valid && item->name == name )
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioCacheInvalidate ( AudioCache *cache )
|
||||
{
|
||||
AudioCacheItem *item, *head;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( cache, AudioCache );
|
||||
|
||||
item = head = (AudioCacheItem *) &cache->items ;
|
||||
|
||||
while ( (item = (AudioCacheItem *) item->nd.next ) != head )
|
||||
{
|
||||
item->valid = FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioCacheOpenCB* AudioCacheSetOpenCB ( AudioCache *cache, AudioCacheOpenCB *cb )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( cache, AudioCache );
|
||||
|
||||
AudioCacheOpenCB *old = cache->openAssetCB;
|
||||
cache->openAssetCB = cb;
|
||||
return old;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioCacheItem* AudioCacheLoadItem ( AudioCache *cache, const char *name )
|
||||
{
|
||||
AudioCacheItem *item;
|
||||
int error;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( cache, AudioCache );
|
||||
|
||||
if ( (item = AudioCacheGetItem ( cache, name )))
|
||||
{
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("ACACHE: %10s - Cached\n", item->name ));
|
||||
#endif
|
||||
|
||||
ListNodeRemove ( &item->nd );
|
||||
ListNodeAppend ( &cache->items, &item->nd );
|
||||
ProfCacheHit ( &cache->profile );
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
ProfCacheMiss ( &cache->profile );
|
||||
// item is not in the cache so load it
|
||||
// see first if the sample exists
|
||||
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("ACACHE: %10s - Loading\n", name ));
|
||||
#endif
|
||||
|
||||
ProfCacheLoadStart ( &cache->profile, 0 );
|
||||
|
||||
if ( !audioCacheAssetOpen( cache, name ))
|
||||
{
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("does not exist\n"));
|
||||
#endif
|
||||
goto none;
|
||||
}
|
||||
|
||||
item = (AudioCacheItem *) MemoryPoolGetItem ( cache->itemPool );
|
||||
|
||||
if ( !item )
|
||||
{
|
||||
// free the oldest item so that we can use it's item struct
|
||||
AudioCacheFreeOldestItem ( cache );
|
||||
item = (AudioCacheItem *) MemoryPoolGetItem ( cache->itemPool );
|
||||
|
||||
if ( !item )
|
||||
{
|
||||
// the oldest item could not be freed because it was still playing
|
||||
DBGPRINTF (("Audio cache overflow\n"));
|
||||
audioCacheAssetClose ( cache );
|
||||
goto none;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare item for use
|
||||
item->name = name;
|
||||
item->cache = cache;
|
||||
ListNodeInit ( &item->nd );
|
||||
LockInit ( &item->lock );
|
||||
AudioSampleInit ( &item->sample );
|
||||
AudioSampleSetName ( &item->sample, name );
|
||||
AudioFormatInit ( &item->format );
|
||||
item->sample.Format = &item->format;
|
||||
DBG_SET_TYPE ( item, AudioCacheItem );
|
||||
|
||||
error = FALSE;
|
||||
|
||||
// ok load sample data in to cache
|
||||
{
|
||||
int bytesToTransfer;
|
||||
int bytes;
|
||||
int bytesTransfered;
|
||||
|
||||
bytesToTransfer = cache->assetBytesLeft;
|
||||
|
||||
while ( bytesToTransfer )
|
||||
{
|
||||
AudioFrame *frame;
|
||||
void *data;
|
||||
|
||||
if ( (bytes = cache->frameSize ) > bytesToTransfer )
|
||||
{
|
||||
bytes = bytesToTransfer;
|
||||
}
|
||||
|
||||
while ( ! (frame = (AudioFrame *) MemoryPoolGetItem ( cache->framePool )))
|
||||
{
|
||||
if ( !AudioCacheFreeOldestItem ( cache ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !frame )
|
||||
{
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
data = (void *) ( (uint) frame + sizeof ( AudioFrame ));
|
||||
|
||||
AudioFrameInit ( frame, data, bytes );
|
||||
AudioSampleAddFrame ( &item->sample, frame );
|
||||
|
||||
bytesTransfered = audioCacheAssetRead ( cache, data, bytes );
|
||||
ProfCacheAddLoadBytes ( &cache->profile, bytesTransfered );
|
||||
ProfCacheAddPage ( &cache->profile );
|
||||
ProfCacheFill ( &cache->profile, bytesTransfered );
|
||||
|
||||
if ( bytesTransfered != bytes )
|
||||
{
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
bytesToTransfer -= bytesTransfered;
|
||||
}
|
||||
}
|
||||
|
||||
if ( error )
|
||||
{
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("FAILED\n"));
|
||||
#endif
|
||||
AudioCacheItemFree ( item );
|
||||
goto none;
|
||||
}
|
||||
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("done\n"));
|
||||
#endif
|
||||
|
||||
// update the format structure
|
||||
memcpy ( &item->format, &cache->assetFormat, sizeof ( AudioFormat) );
|
||||
|
||||
|
||||
ListNodeAppend ( &cache->items, &item->nd );
|
||||
item->valid = TRUE;
|
||||
audioCacheAssetClose ( cache );
|
||||
|
||||
ProfCacheLoadEnd ( &cache->profile );
|
||||
return item;
|
||||
|
||||
none:
|
||||
|
||||
ProfCacheLoadEnd ( &cache->profile );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
// AudioCacheFreeOldestItem()
|
||||
// Free the oldest UNUSED item in the list. These should tend to be
|
||||
// towards the end of the list, as old events should expire and unlock.
|
||||
// But not always (e.g. loops), so don't count on it.
|
||||
|
||||
int AudioCacheFreeOldestItem( AudioCache *cache )
|
||||
{
|
||||
AudioCacheItem *item;
|
||||
|
||||
DBG_ASSERT_TYPE( cache, AudioCache );
|
||||
|
||||
item = (AudioCacheItem*) ListNodePrev( &cache->items );
|
||||
|
||||
while ( item )
|
||||
{
|
||||
if ( !AudioCacheItemInUse( item ) )
|
||||
{
|
||||
AudioCacheItemFree( item );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
item = (AudioCacheItem*) ListNodePrev( (ListNode*) item );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioCacheItemLock ( AudioCacheItem *item )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( item, AudioCacheItem );
|
||||
|
||||
LockAcquire ( &item->lock );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioCacheItemUnlock ( AudioCacheItem *item )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( item, AudioCacheItem );
|
||||
|
||||
LockRelease ( &item->lock );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioCacheItemInUse ( AudioCacheItem *item )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( item, AudioCacheItem );
|
||||
|
||||
return Locked ( &item->lock );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioCacheItemFree ( AudioCacheItem *item )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( item, AudioCacheItem );
|
||||
|
||||
if ( ListNodeInList ( &item->nd ))
|
||||
{
|
||||
ListNodeRemove ( &item->nd );
|
||||
}
|
||||
|
||||
DBG_MSGASSERT ( !AudioCacheItemInUse ( item ), ("cache item is still in use"));
|
||||
|
||||
#if DEBUG_CACHE
|
||||
DBGPRINTF (("ACACHE: %10s - Freeing\n", AudioBagGetItemName ( item->cache->bag, item->id )));
|
||||
#endif
|
||||
|
||||
// return frames to frame pool
|
||||
{
|
||||
AudioFrame *frame;
|
||||
|
||||
while ( (frame = (AudioFrame *) ListNodeNext ( &item->sample.Frames )) )
|
||||
{
|
||||
ListNodeRemove ( &frame->nd );
|
||||
ProfCacheRemove ( &item->cache->profile, frame->Bytes );
|
||||
AudioFrameDeinit ( frame );
|
||||
ProfCacheRemovePage ( &item->cache->profile );
|
||||
MemoryPoolReturnItem ( item->cache->framePool, frame );
|
||||
}
|
||||
}
|
||||
|
||||
AudioSampleDeinit ( &item->sample );
|
||||
DBG_INVALIDATE_TYPE ( item );
|
||||
MemoryPoolReturnItem ( item->cache->itemPool, item );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioSample* AudioCacheItemSample ( AudioCacheItem *item )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( item, AudioCacheItem );
|
||||
|
||||
return &item->sample;
|
||||
}
|
||||
|
710
Generals/Code/Libraries/Source/WPAudio/AUD_Channel.cpp
Normal file
710
Generals/Code/Libraries/Source/WPAudio/AUD_Channel.cpp
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audchanl.cpp **
|
||||
** **
|
||||
** Created by: 11/16/96 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/memory.h>
|
||||
#include <wpaudio/list.h>
|
||||
#include <wpaudio/channel.h>
|
||||
#include <wpaudio/device.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioChannel)
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
static int audioChannelSampleDone ( AudioChannel *chan );
|
||||
static int audioChannelNextSample ( AudioChannel *chan );
|
||||
static int audioChannelNextFrame ( AudioChannel *chan );
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioChannel* audioChannelCreate ( AudioDevice *dev )
|
||||
{
|
||||
AudioChannel *chan = NULL;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( dev , AudioDevice );
|
||||
|
||||
|
||||
ALLOC_STRUCT ( chan, AudioChannel );
|
||||
|
||||
DBG_SET_TYPE ( chan, AudioChannel );
|
||||
|
||||
ListNodeInit ( &chan->nd );
|
||||
AudioControlInit ( &chan->Control );
|
||||
AudioAttribsInit ( &chan->attribs );
|
||||
audioChannelMakeStandard ( chan ); // set up for standard processing
|
||||
|
||||
chan->Device = dev;
|
||||
chan->driver = dev->driver;
|
||||
|
||||
chan->current_format = dev->DefaultFormat;
|
||||
chan->format_changed = FALSE;
|
||||
chan->drv_format_changed = FALSE;
|
||||
#ifndef IG_FINAL_RELEASE
|
||||
chan->sample_name[0] = 0;
|
||||
#endif
|
||||
|
||||
if ( dev->driver->openChannel ( chan ) != vNO_ERROR )
|
||||
{
|
||||
DBGPRINTF (("Audio driver failed to open a new channel\n"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
return chan;
|
||||
|
||||
error:
|
||||
|
||||
if ( chan )
|
||||
{
|
||||
audioChannelDestroy ( chan );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void audioChannelDestroy ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->closeChannel ( chan );
|
||||
|
||||
AudioMemFree ( chan );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void audioChannelMakeStandard ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
// reset callbacks
|
||||
chan->drvCBNextFrame = (AudioChannelCB *) audioChannelNextFrame;
|
||||
chan->drvCBNextSample = (AudioChannelCB *) audioChannelNextSample;
|
||||
chan->drvCBSampleDone = (AudioChannelCB *) audioChannelSampleDone;
|
||||
chan->CB_NextFrame = NULL;
|
||||
chan->CB_NextSample = NULL;
|
||||
chan->CB_SampleDone = NULL;
|
||||
chan->CB_Stop = NULL;
|
||||
chan->Data = NULL;
|
||||
chan->Type = AUDIO_CHANNEL_TYPE_STD;
|
||||
|
||||
// reset control
|
||||
AudioControlInit ( &chan->Control );
|
||||
chan->Control.Priority = AUD_NORMAL_PRIORITY;
|
||||
|
||||
// reset attribs
|
||||
chan->GroupAttribs = audioStdChannelAttribs;
|
||||
chan->SfxAttribs = NULL;
|
||||
chan->CompAttribs = NULL;
|
||||
chan->FadeAttribs = NULL;
|
||||
AudioAttribsInit ( &chan->ChannelAttribs );
|
||||
|
||||
// reset sequencer
|
||||
|
||||
// clear audio
|
||||
chan->sample = NULL;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void audioChannelRecalcAttribs ( AudioChannel *chan )
|
||||
{
|
||||
AudioDevice *dev;
|
||||
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
dev = (AudioDevice *) chan->Device;
|
||||
|
||||
DBG_ASSERT_TYPE ( dev, AudioDevice );
|
||||
|
||||
|
||||
AudioAttribsInit ( &chan->attribs );
|
||||
AudioAttribsApply ( &chan->attribs, &chan->ChannelAttribs );
|
||||
AudioAttribsUsed ( &chan->ChannelAttribs );
|
||||
|
||||
if ( chan->SfxAttribs )
|
||||
{
|
||||
AudioAttribsApply ( &chan->attribs, chan->SfxAttribs );
|
||||
AudioAttribsUsed ( chan->SfxAttribs );
|
||||
}
|
||||
|
||||
if ( chan->GroupAttribs )
|
||||
{
|
||||
AudioAttribsApply ( &chan->attribs, chan->GroupAttribs );
|
||||
}
|
||||
|
||||
if ( chan->CompAttribs )
|
||||
{
|
||||
AudioAttribsApply ( &chan->attribs, chan->CompAttribs );
|
||||
}
|
||||
|
||||
if ( chan->FadeAttribs )
|
||||
{
|
||||
AudioAttribsApply ( &chan->attribs, chan->FadeAttribs );
|
||||
}
|
||||
|
||||
AudioAttribsApply ( &chan->attribs, &dev->Attribs );
|
||||
|
||||
if ( dev->GroupAttribs )
|
||||
{
|
||||
AudioAttribsApply ( &chan->attribs, dev->GroupAttribs );
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static int audioChannelNextFrame ( AudioChannel *chan )
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
DBG_ASSERT ( chan != NULL );
|
||||
|
||||
if ( chan->CB_NextFrame )
|
||||
{
|
||||
// user is controlling frame access
|
||||
if ( (err = chan->CB_NextFrame ( chan )) != vNO_ERROR )
|
||||
{
|
||||
// there was an error
|
||||
DBGPRINTF(("Frame error:\n"));
|
||||
chan->bytesInFrame = 0;
|
||||
chan->bytesRemaining = 0;
|
||||
chan->frameData = NULL;
|
||||
return err;
|
||||
};
|
||||
|
||||
DBG_ASSERT ( chan->bytesInFrame >= 0 );
|
||||
DBG_ASSERT ( chan->bytesRemaining >= 0 );
|
||||
|
||||
return vNO_ERROR;
|
||||
|
||||
}
|
||||
|
||||
// user is not controlling frame access so we handle the default behaviour
|
||||
|
||||
DBG_ASSERT ( chan->bytesRemaining >= 0 ); // something corrupted this field
|
||||
|
||||
if ( chan->frame )
|
||||
{
|
||||
if ( ( chan->frame = (AudioFrame*) ListNodeNext ( &chan->frame->nd )) )
|
||||
{
|
||||
// there is more data to be got
|
||||
chan->frameData = (char *) chan->frame->Data;
|
||||
chan->bytesInFrame = chan->frame->Bytes;
|
||||
chan->bytesRemaining = chan->bytesInFrame;
|
||||
DBG_MSGASSERT ( chan->frame->sample == chan->sample, ("frame does not belong to sample") );
|
||||
return vNO_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// data has been exhausted
|
||||
|
||||
chan->bytesInFrame = 0; // no more frames, drvCBNextSample() will be called
|
||||
|
||||
return vNO_ERROR;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static int audioChannelNextSample ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT ( chan != NULL );
|
||||
|
||||
if (chan->Control.LoopCount)
|
||||
{
|
||||
if ( chan->Control.LoopCount != AUDIO_CTRL_LOOP_FOREVER )
|
||||
{
|
||||
chan->Control.LoopCount--;
|
||||
}
|
||||
AudioChannelSetSample ( chan, chan->sample );
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioChannelSetSample ( chan, NULL );
|
||||
}
|
||||
|
||||
if ( chan->CB_NextSample)
|
||||
{
|
||||
chan->CB_NextSample ( chan );
|
||||
}
|
||||
|
||||
|
||||
if ( chan->sample )
|
||||
{
|
||||
chan->driver->queueIt ( chan );
|
||||
}
|
||||
|
||||
return vNO_ERROR;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static int audioChannelSampleDone ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
// reset channel back to default
|
||||
chan->sample = NULL;
|
||||
FLAGS_CLEAR ( chan->Control.Status, mAUDIO_CTRL_PLAYING|mAUDIO_CTRL_PAUSED );
|
||||
chan->Control.LoopCount = 0;
|
||||
AudioAttribsInit ( &chan->ChannelAttribs );
|
||||
|
||||
#ifndef IG_FINAL_RELEASE
|
||||
chan->sample_name[0] = 0;
|
||||
#endif
|
||||
|
||||
|
||||
if ( chan->CB_SampleDone )
|
||||
{
|
||||
return chan->CB_SampleDone ( chan );
|
||||
}
|
||||
|
||||
return vNO_ERROR;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioChannelTaken ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
return chan->Control.Status & mAUDIO_CTRL_ALLOCATED;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelReserve ( AudioChannel *chan, AudioChannelType type )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
DBG_ASSERT ( chan->Type == AUDIO_CHANNEL_TYPE_STD ); // you can only reserve standard channels
|
||||
|
||||
chan->Type = type;
|
||||
|
||||
AudioChannelStop ( chan );
|
||||
FLAGS_SET ( chan->Control.Status, mAUDIO_CTRL_ALLOCATED );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelRelease ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
if ( chan->Control.Status & mAUDIO_CTRL_ALLOCATED)
|
||||
{
|
||||
FLAGS_CLEAR ( chan->Control.Status, mAUDIO_CTRL_ALLOCATED );
|
||||
chan->Type = AUDIO_CHANNEL_TYPE_STD;
|
||||
audioChannelMakeStandard ( chan );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelDestroy ( AudioChannel *chan)
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
AudioChannelStop ( chan ); // stop anything that is playing
|
||||
|
||||
audioRemoveChannel ( chan );
|
||||
|
||||
audioChannelDestroy ( chan );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelStop ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan);
|
||||
if ( chan->Control.Status & (mAUDIO_CTRL_PLAYING|mAUDIO_CTRL_PAUSED) )
|
||||
{
|
||||
chan->driver->stop ( chan );
|
||||
DBG_ASSERT ( !(chan->Control.Status & (mAUDIO_CTRL_PLAYING|mAUDIO_CTRL_PAUSED)) );
|
||||
}
|
||||
chan->driver->unlock ( chan );
|
||||
|
||||
if ( chan->CB_Stop )
|
||||
{
|
||||
chan->CB_Stop ( chan );
|
||||
}
|
||||
|
||||
chan->sample = NULL;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelPause ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
if ( chan->Control.Status & mAUDIO_CTRL_PLAYING )
|
||||
{
|
||||
FLAGS_CLEAR (chan->Control.Status, mAUDIO_CTRL_PLAYING);
|
||||
chan->driver->pause ( chan );
|
||||
FLAGS_SET (chan->Control.Status, mAUDIO_CTRL_PAUSED);
|
||||
}
|
||||
chan->driver->unlock ( chan );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelResume ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
if ( chan->Control.Status & mAUDIO_CTRL_PAUSED )
|
||||
{
|
||||
chan->driver->resume ( chan );
|
||||
FLAGS_CLEAR (chan->Control.Status, mAUDIO_CTRL_PAUSED);
|
||||
FLAGS_SET (chan->Control.Status, mAUDIO_CTRL_PLAYING);
|
||||
}
|
||||
chan->driver->unlock ( chan );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelLock ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelUnlock ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->unlock ( chan );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelUse ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
FLAGS_SET ( chan->Control.Status, mAUDIO_CTRL_INUSE);
|
||||
chan->driver->unlock ( chan );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelNoUse ( AudioChannel *chan )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
FLAGS_CLEAR ( chan->Control.Status, mAUDIO_CTRL_INUSE);
|
||||
chan->driver->unlock ( chan );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioChannelStart ( AudioChannel *chan )
|
||||
{
|
||||
int err = ERROR_CODE_FAIL;
|
||||
|
||||
|
||||
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
if ( (chan->Control.Status & (mAUDIO_CTRL_PAUSED | mAUDIO_CTRL_PLAYING)))
|
||||
{
|
||||
DBGPRINTF (("Failed to start channel as channel is currently active\n"));
|
||||
return ERROR_CODE_NO_CHANNEL;
|
||||
}
|
||||
if ( chan->sample == NULL )
|
||||
{
|
||||
DBGPRINTF (("Failed to start channel as no sample data was given\n"));
|
||||
return ERROR_CODE_MISSING_DATA;
|
||||
}
|
||||
|
||||
AudioAttribsUpdate ( &chan->ChannelAttribs );
|
||||
audioChannelRecalcAttribs ( chan );
|
||||
|
||||
chan->driver->lock ( chan );
|
||||
if ( (err = chan->driver->start ( chan )) == vNO_ERROR )
|
||||
{
|
||||
FLAGS_SET ( chan->Control.Status, mAUDIO_CTRL_PLAYING);
|
||||
}
|
||||
chan->driver->unlock ( chan );
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioChannelSetSample ( AudioChannel *chan, AudioSample *sample )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( audioInitialized ); // AudioSetUp() was not called
|
||||
DBG_ASSERT_TYPE ( chan, AudioChannel );
|
||||
|
||||
if ( (chan->sample = sample) )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample);
|
||||
|
||||
#ifndef IG_FINAL_RELEASE
|
||||
strncpy ( chan->sample_name, sample->name, sizeof(chan->sample_name));
|
||||
chan->sample_name[ sizeof(chan->sample_name) -1 ] = 0;
|
||||
#endif
|
||||
|
||||
if ( chan->frame = AudioSampleFirstFrame ( sample ) )
|
||||
{
|
||||
chan->frameData = (char *) chan->frame->Data;
|
||||
chan->bytesInFrame = chan->frame->Bytes;
|
||||
chan->bytesRemaining = chan->bytesInFrame;
|
||||
sample->Data = NULL;
|
||||
DBG_MSGASSERT ( chan->frame->sample == sample, ("frame does not belong to sample") );
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->frameData = chan->sample->Data;
|
||||
chan->bytesInFrame = chan->sample->Bytes;
|
||||
chan->bytesRemaining = chan->bytesInFrame;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioChannelSetFormat ( AudioChannel *chan, AudioFormat *new_format )
|
||||
{
|
||||
|
||||
|
||||
if ( !memcmp ( new_format, &chan->current_format, sizeof ( AudioFormat )))
|
||||
{
|
||||
chan->format_changed = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
chan->format_changed = TRUE;
|
||||
chan->current_format = *new_format;
|
||||
}
|
||||
|
||||
return chan->format_changed;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioChannelIsAudible ( AudioChannel *chan )
|
||||
{
|
||||
return (chan->Control.Status & mAUDIO_CTRL_PLAYING);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioControlInit ( AudioControl *ctrl )
|
||||
{
|
||||
ctrl->LoopCount = 0;
|
||||
ctrl->Status = 0;
|
||||
}
|
2188
Generals/Code/Libraries/Source/WPAudio/AUD_DSoundDriver.cpp
Normal file
2188
Generals/Code/Libraries/Source/WPAudio/AUD_DSoundDriver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1824
Generals/Code/Libraries/Source/WPAudio/AUD_Device.cpp
Normal file
1824
Generals/Code/Libraries/Source/WPAudio/AUD_Device.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3132
Generals/Code/Libraries/Source/WPAudio/AUD_Events.cpp
Normal file
3132
Generals/Code/Libraries/Source/WPAudio/AUD_Events.cpp
Normal file
File diff suppressed because it is too large
Load Diff
288
Generals/Code/Libraries/Source/WPAudio/AUD_Level.cpp
Normal file
288
Generals/Code/Libraries/Source/WPAudio/AUD_Level.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audlevel.cpp **
|
||||
** **
|
||||
** Created by: 11/16/95 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/level.h>
|
||||
#include <wpaudio/time.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioLevel )
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioLevelInit ( AudioLevel *level, int startLevel )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( level != NULL );
|
||||
DBG_SET_TYPE ( level, AudioLevel );
|
||||
|
||||
level->flags = 0;
|
||||
level->lastTime = AudioGetTime ();
|
||||
AudioLevelSetDuration ( level, SECONDS(1), AUDIO_LEVEL_MAX);
|
||||
AudioLevelSet ( level, startLevel );
|
||||
AudioLevelUpdate ( level );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioLevelSet ( AudioLevel *level, int newLevel )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
DBG_ASSERT (newLevel>=AUDIO_LEVEL_MIN);
|
||||
DBG_ASSERT (newLevel<=AUDIO_LEVEL_MAX);
|
||||
|
||||
level->flags |= AUDIO_LEVEL_SET;
|
||||
level->newLevel = (newLevel<<AUDIO_LEVEL_SCALE);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioLevelForce( AudioLevel *level)
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
|
||||
level->flags |= AUDIO_LEVEL_SET;
|
||||
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioLevelApply ( AudioLevel *level, int val )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
DBG_ASSERT (val >= AUDIO_LEVEL_MIN_VAL);
|
||||
DBG_ASSERT (val <= AUDIO_LEVEL_MAX_VAL);
|
||||
|
||||
return AUDIO_LEVEL_APPLY(level,val);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioLevelAdjust ( AudioLevel *level, int newLevel )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
DBG_ASSERT (newLevel>=AUDIO_LEVEL_MIN);
|
||||
DBG_ASSERT (newLevel<=AUDIO_LEVEL_MAX);
|
||||
|
||||
level->flags &= ~AUDIO_LEVEL_SET;
|
||||
if ( level->newLevel == level->level)
|
||||
{
|
||||
level->lastTime = AudioGetTime ();
|
||||
}
|
||||
level->newLevel = newLevel<<AUDIO_LEVEL_SCALE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioLevelSetDuration ( AudioLevel *level, TimeStamp time, int range )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
DBG_ASSERT ( time != 0 );
|
||||
DBG_ASSERT (range > 0);
|
||||
DBG_ASSERT (range <= AUDIO_LEVEL_MAX);
|
||||
|
||||
level->change = (range<< AUDIO_LEVEL_SCALE) / (uint) time;
|
||||
level->duration = time;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioLevelUpdate ( AudioLevel *level )
|
||||
{
|
||||
int dif;
|
||||
int delta; // amount to move by this update
|
||||
TimeStamp time, thisTime;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( level, AudioLevel );
|
||||
|
||||
if ( (dif = (level->newLevel - level->level)) )
|
||||
{
|
||||
if (level->flags & AUDIO_LEVEL_SET )
|
||||
{
|
||||
level->level = level->newLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// calculate what the delta change is for this update
|
||||
thisTime = AudioGetTime ( ) ;
|
||||
time = thisTime - level->lastTime;
|
||||
level->lastTime = thisTime; // remember time of this update
|
||||
|
||||
// the next check avoid overflowing the delta
|
||||
if (time > level->duration)
|
||||
{
|
||||
time = level->duration;
|
||||
}
|
||||
|
||||
delta = level->change * (uint) time;
|
||||
|
||||
if (dif<0)
|
||||
{
|
||||
if ( delta > (-dif))
|
||||
{
|
||||
level->level += dif;
|
||||
}
|
||||
else
|
||||
{
|
||||
level->level -= delta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( delta > dif )
|
||||
{
|
||||
level->level += dif;
|
||||
}
|
||||
else
|
||||
{
|
||||
level->level += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
// there was a change in the level
|
||||
level->flags |= AUDIO_LEVEL_CHANGED;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// there has been no change this update
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioLevelGetVal( AudioLevel *level )
|
||||
{
|
||||
return (level->newLevel>>AUDIO_LEVEL_SCALE);
|
||||
}
|
||||
|
418
Generals/Code/Libraries/Source/WPAudio/AUD_List.cpp
Normal file
418
Generals/Code/Libraries/Source/WPAudio/AUD_List.cpp
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audlists.cpp **
|
||||
** **
|
||||
** Created by: 04/01/95 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/list.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListInit ( ListHead *head )
|
||||
{
|
||||
head->prev = head->next = head;
|
||||
head->pri = (Priority) head; // this identifies the node as a head node
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListNodeInit ( ListNode *node )
|
||||
{
|
||||
node->prev = node->next= node;
|
||||
node->pri = 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int ListAddNodeSortAscending( ListHead *head, ListNode *new_node )
|
||||
{
|
||||
ListNode *node;
|
||||
Priority pri;
|
||||
int index;
|
||||
|
||||
index = 0;
|
||||
pri = new_node->pri;
|
||||
node = (ListNode*) head;
|
||||
while( (node = ListNodeNext ( node )))
|
||||
{
|
||||
if ( pri <= node->pri )
|
||||
{
|
||||
ListNodeInsert ( node, new_node );
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
ListNodeInsert ( head, new_node );
|
||||
return index;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListAddNode( ListHead *head, ListNode *new_node )
|
||||
{
|
||||
ListNode *node;
|
||||
Priority pri;
|
||||
|
||||
|
||||
pri = new_node->pri;
|
||||
node = (ListNode*) head;
|
||||
while( (node = ListNodeNext ( node )))
|
||||
{
|
||||
if (node->pri <= pri )
|
||||
{
|
||||
ListNodeInsert ( node, new_node );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ListNodeInsert ( head, new_node );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListAddNodeAfter( ListHead *head, ListNode *new_node )
|
||||
{
|
||||
ListNode *node;
|
||||
Priority pri;
|
||||
|
||||
|
||||
pri = new_node->pri;
|
||||
node = (ListNode*) head;
|
||||
while( (node = ListNodeNext ( node )))
|
||||
{
|
||||
if (node->pri < pri )
|
||||
{
|
||||
ListNodeInsert ( node, new_node );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ListNodeInsert ( head, new_node );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListMerge( ListHead *from, ListHead *to )
|
||||
{
|
||||
ListNode *first,
|
||||
*last,
|
||||
*node;
|
||||
|
||||
first = from->next;
|
||||
last = from->prev;
|
||||
|
||||
if ( first == (ListNode*) from )
|
||||
{
|
||||
/* the from list is empty so there is nothing to do */
|
||||
return;
|
||||
}
|
||||
|
||||
node = to->prev;
|
||||
node->next = first;
|
||||
first->prev = node;
|
||||
last->next = (ListNode*) to;
|
||||
to->prev = last;
|
||||
|
||||
ListInit ( from ); /* make the from list empty now */
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int ListCountItems ( ListHead *head )
|
||||
{
|
||||
ListNode *node;
|
||||
int count = 0;
|
||||
|
||||
node = head->next;
|
||||
|
||||
while(node!=(ListNode*)head)
|
||||
{
|
||||
count++;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListFirstItem ( ListHead *head )
|
||||
{
|
||||
return ListNextItem ((ListNode*) head );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListNextItem ( ListNode *node )
|
||||
{
|
||||
if ( !node )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ( ListNodeNext ( node ));
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListGetItem( ListHead *head, int number )
|
||||
{
|
||||
ListNode *node;
|
||||
|
||||
node = head->next;
|
||||
|
||||
while( node != (ListNode*) head )
|
||||
{
|
||||
if ( number-- == 0 )
|
||||
{
|
||||
return node;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListNodeInsert( ListNode *node, ListNode *new_node )
|
||||
{
|
||||
new_node->prev = node->prev;
|
||||
new_node->next = node;
|
||||
node->prev = new_node;
|
||||
new_node->prev->next = new_node;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListNodeAppend( ListNode *node, ListNode *new_node )
|
||||
{
|
||||
new_node->prev = node;
|
||||
new_node->next = node->next;
|
||||
node->next = new_node;
|
||||
new_node->next->prev = new_node;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ListNodeRemove( ListNode *node )
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
node->prev = node->next = node; // so we know that the node is not in a list
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListNodeNext( ListNode *node )
|
||||
{
|
||||
ListNode *next;
|
||||
|
||||
next = node->next;
|
||||
|
||||
if ( next && ListNodeIsHead ( next ))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListNodePrev (ListNode *node)
|
||||
{
|
||||
ListNode *next;
|
||||
|
||||
next = node->prev;
|
||||
|
||||
if ( ListNodeIsHead ( next ))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListNodeLoopNext (ListNode *node)
|
||||
{
|
||||
ListNode *next;
|
||||
|
||||
next = node->next;
|
||||
|
||||
if ( ListNodeIsHead ( next ))
|
||||
{
|
||||
// skip head node
|
||||
next = next->next;
|
||||
if ( ListNodeIsHead ( next ))
|
||||
{
|
||||
return NULL; // it is an empty list
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
ListNode* ListNodeLoopPrev (ListNode *node)
|
||||
{
|
||||
ListNode *next;
|
||||
|
||||
next = node->prev;
|
||||
|
||||
if ( ListNodeIsHead ( next ))
|
||||
{
|
||||
// skip head node
|
||||
next = next->prev;
|
||||
if ( ListNodeIsHead ( next ))
|
||||
{
|
||||
return NULL; // it is an empty list
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
|
158
Generals/Code/Libraries/Source/WPAudio/AUD_Lock.cpp
Normal file
158
Generals/Code/Libraries/Source/WPAudio/AUD_Lock.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audlock.cpp **
|
||||
** **
|
||||
** Created by: 04/01/95 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/lock.h>
|
||||
|
||||
DBG_DECLARE_TYPE ( Lock )
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void LockInit ( volatile Lock *lock )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( lock != NULL);
|
||||
|
||||
LOCK_INIT(lock);
|
||||
|
||||
DBG_SET_TYPE ( lock, Lock );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void LockAcquire ( volatile Lock *lock)
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( lock, Lock);
|
||||
DBG_ASSERT ( lock->count >= 0 );
|
||||
|
||||
LOCK_ACQUIRE (lock);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void LockRelease ( volatile Lock *lock)
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( lock, Lock);
|
||||
DBG_ASSERT ( lock->count > 0 );
|
||||
|
||||
LOCK_RELEASE(lock);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int Locked ( volatile Lock *lock)
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( lock, Lock);
|
||||
DBG_ASSERT ( lock->count >= 0 );
|
||||
|
||||
return LOCKED(lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
277
Generals/Code/Libraries/Source/WPAudio/AUD_Memory.cpp
Normal file
277
Generals/Code/Libraries/Source/WPAudio/AUD_Memory.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audmpool.cpp **
|
||||
** **
|
||||
** Created by: 10/23/95 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/memory.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioMemoryPool )
|
||||
DBG_DECLARE_TYPE ( MemoryItem )
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioMemoryPool* MemoryPoolCreate( uint items, uint size )
|
||||
{
|
||||
uint poolsize;
|
||||
AudioMemoryPool *pool;
|
||||
MemoryItem *item;
|
||||
uint i;
|
||||
|
||||
|
||||
DBG_ASSERT ( items > 0 );
|
||||
DBG_ASSERT ( size > 0 );
|
||||
|
||||
poolsize = items*(size + sizeof(MemoryItem)) + sizeof (AudioMemoryPool);
|
||||
|
||||
if ((pool = (AudioMemoryPool *) AudioMemAlloc ( poolsize )))
|
||||
{
|
||||
|
||||
item = (MemoryItem *)( (uint)pool + (uint) sizeof(AudioMemoryPool));
|
||||
|
||||
pool->next = item;
|
||||
DBG_CODE ( pool->itemsOut = 0;)
|
||||
DBG_CODE ( pool->numItems = items;)
|
||||
DBG_SET_TYPE ( pool, AudioMemoryPool );
|
||||
|
||||
for ( i=0; i < items-1; i++)
|
||||
{
|
||||
DBG_SET_TYPE ( item, MemoryItem );
|
||||
item->next = (MemoryItem *) ( (uint) item + (uint) (sizeof(MemoryItem) + size) );
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
item->next = NULL;
|
||||
DBG_SET_TYPE ( item, MemoryItem );
|
||||
|
||||
}
|
||||
|
||||
return pool;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void MemoryPoolDestroy ( AudioMemoryPool *pool )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( pool, AudioMemoryPool );
|
||||
|
||||
DBG_CODE
|
||||
(
|
||||
if ( pool->itemsOut > 0 )
|
||||
{
|
||||
DBGPRINTF ( ( "Destroying memory pool with %d items still out\n", pool->itemsOut) );
|
||||
}
|
||||
)
|
||||
|
||||
AudioMemFree ( pool );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void *MemoryPoolGetItem ( AudioMemoryPool *pool )
|
||||
{
|
||||
MemoryItem *item = NULL;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( pool, AudioMemoryPool );
|
||||
|
||||
if (! (item = pool->next) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBG_CODE ( pool->itemsOut++;)
|
||||
|
||||
DBG_MSGASSERT ( pool->itemsOut <= pool->numItems,( "pool overflow" ));
|
||||
|
||||
DBG_ASSERT_TYPE ( item, MemoryItem ); // !!! Memory corruption !!!
|
||||
|
||||
pool->next = item->next;
|
||||
|
||||
return (void *) ( (uint) item + (uint) sizeof(MemoryItem));
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void MemoryPoolReturnItem ( AudioMemoryPool *pool, void *data )
|
||||
{
|
||||
MemoryItem *item;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( pool, AudioMemoryPool );
|
||||
DBG_ASSERT_PTR ( data );
|
||||
|
||||
item = (MemoryItem *) ( (uint) data - (uint) sizeof(MemoryItem));
|
||||
|
||||
DBG_ASSERT_TYPE ( item, MemoryItem ); // returning invalid item to pool
|
||||
|
||||
item->next = pool->next;
|
||||
pool->next = item;
|
||||
|
||||
DBG_MSGASSERT ( pool->itemsOut > 0,( "Pool underflow" )); // returning more items than were taken
|
||||
|
||||
DBG_CODE ( pool->itemsOut--; )
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int MemoryPoolCount ( AudioMemoryPool *pool )
|
||||
{
|
||||
MemoryItem *item = NULL;
|
||||
int count = 0;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( pool, AudioMemoryPool );
|
||||
|
||||
if ( (item = pool->next) )
|
||||
{
|
||||
while ( item )
|
||||
{
|
||||
count++;
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioAddSlash ( char *string )
|
||||
{
|
||||
int len = strlen ( string );
|
||||
|
||||
if ( len )
|
||||
{
|
||||
if ( string[len-1] != '\\' )
|
||||
{
|
||||
string[len] = '\\';
|
||||
string[len+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioHasPath ( const char *string )
|
||||
{
|
||||
return ( strchr ( string, ':' ) || strchr ( string, '\\' ) || strchr ( string, '/' ) || strchr ( string, '.'));
|
||||
}
|
||||
|
636
Generals/Code/Libraries/Source/WPAudio/AUD_Profiler.cpp
Normal file
636
Generals/Code/Libraries/Source/WPAudio/AUD_Profiler.cpp
Normal file
@@ -0,0 +1,636 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audprof.cpp **
|
||||
** **
|
||||
** Created by: mm/dd/yy <author> **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <wpaudio/profiler.h>
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef IG_FINAL_RELEASE
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheInit ( ProfileData *prof, int pages, int pageSize )
|
||||
{
|
||||
|
||||
memset ( prof, 0, sizeof ( ProfileData ));
|
||||
if ( !QueryPerformanceFrequency( (LARGE_INTEGER*) &prof->freq ))
|
||||
{
|
||||
prof->freq = 0;
|
||||
}
|
||||
prof->update = prof->freq;
|
||||
prof->cacheSize = pages*pageSize;
|
||||
prof->numPages = pages;
|
||||
prof->pageSize = pageSize;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheDeinit ( ProfileData * )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheNewFrame ( ProfileData *prof )
|
||||
{
|
||||
int total;
|
||||
prof->frames++;
|
||||
|
||||
if ( prof->totalTime > prof->longestFrame )
|
||||
{
|
||||
prof->nextLongestFrame = prof->longestFrame;
|
||||
prof->nextLongestFramePages = prof->longestFramePages;
|
||||
prof->nextLongestFrameBytes = prof->longestFrameBytes;
|
||||
|
||||
prof->longestFrame = prof->totalTime ;
|
||||
prof->longestFrameBytes = prof->totalDataBytes;
|
||||
prof->longestFramePages = prof->pageCount;
|
||||
|
||||
}
|
||||
else if ( prof->totalTime > prof->nextLongestFrame )
|
||||
{
|
||||
prof->nextLongestFrame = prof->totalTime ;
|
||||
prof->nextLongestFrameBytes = prof->totalDataBytes;
|
||||
prof->nextLongestFramePages = prof->pageCount;
|
||||
}
|
||||
|
||||
prof->pageCount = 0;
|
||||
|
||||
if ( (total = prof->hits + prof->misses ))
|
||||
{
|
||||
prof->HitPercent = (prof->hits *100) / total;
|
||||
}
|
||||
|
||||
prof->BytesPerFrame = prof->totalFrameBytes / prof->frames;
|
||||
|
||||
if ( prof->frames > 3*30 )
|
||||
{
|
||||
prof->totalFrameBytes = 0;
|
||||
prof->frames = 0;
|
||||
}
|
||||
|
||||
if ( ! (prof->frames % 30) )
|
||||
{
|
||||
prof->hits = 0;
|
||||
prof->misses = 0;
|
||||
}
|
||||
|
||||
if ( prof->totalTime > prof->update )
|
||||
{
|
||||
int ms;
|
||||
|
||||
ms = (int) ( (prof->totalTime *1000 )/prof->freq);
|
||||
prof->TotalBytesPerSecond = (int) (((unsigned __int64) prof->totalDataBytes *1000)/ ms);
|
||||
prof->totalDataBytes = 0;
|
||||
prof->totalTime = 0;
|
||||
|
||||
ms = (int) ((prof->totalDecompTime *1000 )/prof->freq) ;
|
||||
|
||||
if ( ms )
|
||||
{
|
||||
prof->DecompBytesPerSecond = (int) (((unsigned __int64) prof->totalDecompBytes *1000)/ ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
prof->DecompBytesPerSecond = 0;
|
||||
}
|
||||
|
||||
prof->totalDecompBytes = 0;
|
||||
prof->totalDecompTime = 0;
|
||||
|
||||
ms = (int) ((prof->totalLoadTime *1000 )/prof->freq );
|
||||
|
||||
if ( ms )
|
||||
{
|
||||
prof->LoadBytesPerSecond = (int) (((unsigned __int64)prof->totalLoadBytes *1000)/ ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
prof->LoadBytesPerSecond = 0;
|
||||
}
|
||||
prof->totalLoadBytes = 0;
|
||||
prof->totalLoadTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheLoadStart ( ProfileData *prof, int bytes )
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&prof->start );
|
||||
prof->dbytes = bytes;
|
||||
prof->start_decomp = 0;
|
||||
prof->pageCount++;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheAddLoadBytes ( ProfileData *prof, int bytes )
|
||||
{
|
||||
prof->dbytes += bytes;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheDecompress ( ProfileData *prof, int bytes )
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&prof->start_decomp );
|
||||
prof->lbytes = bytes;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheLoadEnd ( ProfileData *prof )
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&prof->end );
|
||||
prof->totalTime += prof->end - prof->start;
|
||||
prof->totalDataBytes += prof->dbytes;
|
||||
prof->totalFrameBytes += prof->dbytes;
|
||||
if ( prof->start_decomp )
|
||||
{
|
||||
prof->totalLoadTime += prof->start_decomp - prof->start;
|
||||
prof->totalDecompTime += prof->end - prof->start_decomp;
|
||||
prof->totalLoadBytes += prof->lbytes;
|
||||
prof->totalDecompBytes += prof->dbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
prof->totalLoadTime += prof->end - prof->start;
|
||||
prof->totalLoadBytes += prof->dbytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheMiss ( ProfileData *prof )
|
||||
{
|
||||
prof->misses++;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheHit ( ProfileData *prof )
|
||||
{
|
||||
prof->hits++;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheAddPage ( ProfileData *prof )
|
||||
{
|
||||
prof->pagesUsed++;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheRemovePage ( ProfileData *prof )
|
||||
{
|
||||
prof->pagesUsed--;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheFill ( ProfileData *prof, int bytes )
|
||||
{
|
||||
prof->cacheUsed += bytes;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheRemove ( ProfileData *prof, int bytes )
|
||||
{
|
||||
prof->cacheUsed -= bytes;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheText ( ProfileData *prof, void ( *print) ( char *text ) )
|
||||
{
|
||||
char buf[1024];
|
||||
int used;
|
||||
int filled;
|
||||
|
||||
print ("Audio Cache Stats\n");
|
||||
sprintf( buf, "Hits: %d%%\n", prof->HitPercent );
|
||||
print ( buf );
|
||||
|
||||
if ( prof->numPages )
|
||||
{
|
||||
used = (prof->pagesUsed *100)/prof->numPages;
|
||||
}
|
||||
else
|
||||
{
|
||||
used = 0;
|
||||
}
|
||||
|
||||
if ( prof->pagesUsed * prof->pageSize )
|
||||
{
|
||||
filled = (prof->cacheUsed *100)/ (prof->pagesUsed * prof->pageSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
filled = 0;
|
||||
}
|
||||
|
||||
sprintf( buf, "Used: %d%% (%d%%)\n", used, filled );
|
||||
print ( buf );
|
||||
|
||||
sprintf( buf, "KbPS: %d.%02d (%d.%02d,%d.%02d)\n",
|
||||
prof->TotalBytesPerSecond/1024, ((prof->TotalBytesPerSecond%1024)*100)/1024,
|
||||
prof->LoadBytesPerSecond/1024, ((prof->LoadBytesPerSecond%1024)*100)/1024,
|
||||
prof->DecompBytesPerSecond/1024, ((prof->DecompBytesPerSecond%1024)*100)/1024);
|
||||
|
||||
print ( buf );
|
||||
|
||||
sprintf( buf, "KPF: %d.%02d\n",
|
||||
prof->BytesPerFrame/1024, ((prof->BytesPerFrame%1024)*100)/1024 );
|
||||
|
||||
print ( buf );
|
||||
|
||||
sprintf( buf, " LF: %d.%02ds; %d pages; %d Kb\n",
|
||||
(int) (prof->longestFrame/prof->freq), (int)(((prof->longestFrame % prof->freq)*100)/prof->freq),
|
||||
prof->longestFramePages, prof->longestFrameBytes/1024 );
|
||||
|
||||
print ( buf );
|
||||
|
||||
sprintf( buf, "NLF: %d.%02ds; %d pages; %d Kb\n",
|
||||
(int) (prof->nextLongestFrame/prof->freq), (int) (((prof->nextLongestFrame % prof->freq)*100)/prof->freq),
|
||||
prof->nextLongestFramePages, prof->nextLongestFrameBytes/1024 );
|
||||
|
||||
print ( buf );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfCacheUpdateInterval ( ProfileData *prof, int mseconds )
|
||||
{
|
||||
prof->update = (prof->freq * mseconds )/ 1000;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static ProfStamp calc_ticks ( ProfStamp start, ProfStamp end )
|
||||
{
|
||||
if ( start < end )
|
||||
{
|
||||
return end - start;
|
||||
}
|
||||
|
||||
return ((ProfStamp)0xffffffffffffffff) - start + end ;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static void calc_stats ( ProfileCPU &prof )
|
||||
{
|
||||
|
||||
if ( prof.lastCPU )
|
||||
{
|
||||
prof.cpuUsage = (int) ((prof.lastTicks*((ProfStamp)1000))/prof.lastCPU);
|
||||
}
|
||||
else
|
||||
{
|
||||
prof.cpuUsage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUInit ( ProfileCPU &prof )
|
||||
{
|
||||
|
||||
memset ( &prof, 0, sizeof ( ProfileCPU ));
|
||||
|
||||
if ( !QueryPerformanceFrequency( (LARGE_INTEGER*) &prof.freq ))
|
||||
{
|
||||
prof.freq = 0;
|
||||
}
|
||||
prof.updateInterval = SECONDS(1);
|
||||
|
||||
if ( prof.freq )
|
||||
{
|
||||
prof.overflowInterval = SECONDS ( (((ProfStamp) 0xffffffffffffffff) / prof.freq) );
|
||||
|
||||
if ( prof.overflowInterval < prof.updateInterval )
|
||||
{
|
||||
prof.updateInterval = prof.overflowInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUDeinit ( ProfileCPU &prof )
|
||||
{
|
||||
prof;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUStart ( ProfileCPU &prof )
|
||||
{
|
||||
|
||||
if ( prof.state == PROF_STATE_IDLE )
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*)&prof.start );
|
||||
|
||||
if ( prof.lastStart )
|
||||
{
|
||||
prof.totalCPUTicks += calc_ticks ( prof.lastStart, prof.start );
|
||||
}
|
||||
|
||||
prof.lastStart = prof.start;
|
||||
prof.state = PROF_STATE_PROFILING;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUPause ( ProfileCPU &prof )
|
||||
{
|
||||
|
||||
if ( prof.state == PROF_STATE_PROFILING )
|
||||
{
|
||||
ProfStamp end;
|
||||
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*) &end );
|
||||
|
||||
prof.totalTicks += calc_ticks ( prof.start, end );
|
||||
prof.state = PROF_STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUResume ( ProfileCPU &prof )
|
||||
{
|
||||
if ( prof.state == PROF_STATE_PAUSED )
|
||||
{
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*) &prof.start );
|
||||
prof.state = PROF_STATE_PROFILING;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUEnd ( ProfileCPU &prof )
|
||||
{
|
||||
ProfStamp end;
|
||||
|
||||
QueryPerformanceCounter( (LARGE_INTEGER*) &end );
|
||||
|
||||
if ( prof.state != PROF_STATE_IDLE )
|
||||
{
|
||||
if ( prof.start && prof.totalCPUTicks )
|
||||
{
|
||||
prof.totalTicks += calc_ticks ( prof.start, end );
|
||||
}
|
||||
prof.state = PROF_STATE_IDLE;
|
||||
}
|
||||
|
||||
TimeStamp now = AudioGetTime();
|
||||
TimeStamp lastUpdate = now - prof.lastUpdate;
|
||||
|
||||
if ( lastUpdate > prof.updateInterval )
|
||||
{
|
||||
prof.lastUpdate = now;
|
||||
|
||||
if ( lastUpdate < prof.overflowInterval )
|
||||
{
|
||||
// we can use the data
|
||||
prof.lastTicks = prof.totalTicks;
|
||||
prof.lastCPU = prof.totalCPUTicks;
|
||||
calc_stats ( prof );
|
||||
}
|
||||
|
||||
prof.totalTicks = 0;
|
||||
prof.totalCPUTicks = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int ProfileCPUUsage ( ProfileCPU &prof )
|
||||
{
|
||||
return prof.cpuUsage;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int ProfileCPUTicks ( ProfileCPU &prof )
|
||||
{
|
||||
prof;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUSetName ( ProfileCPU &prof, const char *name )
|
||||
{
|
||||
strncpy ( prof.name, name, MAX_PROF_NAME );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void ProfileCPUPrint ( ProfileCPU &prof, void ( *print) ( char *text ) )
|
||||
{
|
||||
char buffer[200];
|
||||
|
||||
if ( prof.freq )
|
||||
{
|
||||
sprintf ( buffer, "%s : CPU %3d.%1d / %I64d", prof.name, prof.cpuUsage/10, prof.cpuUsage%10, prof.lastTicks );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf ( buffer, "%s : CPU (no timer)" );
|
||||
}
|
||||
print ( buffer );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
|
||||
#endif
|
||||
|
632
Generals/Code/Libraries/Source/WPAudio/AUD_Source.cpp
Normal file
632
Generals/Code/Libraries/Source/WPAudio/AUD_Source.cpp
Normal file
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: <filename> **
|
||||
** **
|
||||
** Created by: 04/05/96 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wpaudio/altypes.h>
|
||||
#include <wpaudio/memory.h>
|
||||
#include <wpaudio/time.h>
|
||||
#include <wpaudio/source.h>
|
||||
#include <wsys/file.h>
|
||||
|
||||
//#include "asimp3\mss.h"
|
||||
//#include "asimp3\mp3dec.h"
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
|
||||
DBG_DECLARE_TYPE ( AudioSample )
|
||||
DBG_DECLARE_TYPE ( AudioFormat )
|
||||
DBG_DECLARE_TYPE ( AudioFrame )
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
//
|
||||
// Sample rate in samples/second for [MPEG25][MPEG version][value]
|
||||
//
|
||||
|
||||
static const int sample_rate[2][2][4] =
|
||||
{{
|
||||
{ 22050L,24000L,16000L,22050L },
|
||||
{ 44100L,48000L,32000L,44100L }
|
||||
},
|
||||
{
|
||||
{ 11025L,12000L, 8000L,11025L },
|
||||
{ 44100L,48000L,32000L,44100L }
|
||||
}};
|
||||
|
||||
//
|
||||
// Bit rate in bits/second for [MPEG version][value]
|
||||
//
|
||||
|
||||
static const int bit_rate[2][15] =
|
||||
{
|
||||
{ 0L,8000L,16000L,24000L,32000L,40000L,48000L,56000L,64000L,80000L,96000L,112000L,128000L,144000L,160000L }
|
||||
,
|
||||
{ 0L,32000L,40000L,48000L,56000L,64000L,80000L,96000L,112000L,128000L,160000L,192000L,224000L,256000L,320000L }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
const short MSADPCM_StdCoef[7][2] = {
|
||||
{ 256, 0},
|
||||
{ 512,-256},
|
||||
{ 0, 0},
|
||||
{ 192, 64},
|
||||
{ 240, 0},
|
||||
{ 460,-208},
|
||||
{ 392,-232}
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioSample* AudioCreateSample( uint bytes )
|
||||
{
|
||||
AudioSample *sample;
|
||||
|
||||
|
||||
DBG_ASSERT ( bytes > 0 );
|
||||
|
||||
|
||||
ALLOC_STRUCT ( sample, AudioSample );
|
||||
|
||||
AudioSampleInit ( sample );
|
||||
|
||||
sample->Bytes = bytes;
|
||||
|
||||
if ( ! ( sample->Data = ( char *) AudioMemAlloc ( sample->Bytes ) ))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
return sample;
|
||||
|
||||
error:
|
||||
|
||||
if ( sample )
|
||||
{
|
||||
AudioSampleDestroy ( sample );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioSampleDestroy ( AudioSample *sample )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample );
|
||||
|
||||
if ( sample->Data )
|
||||
{
|
||||
AudioMemFree ( sample->Data );
|
||||
}
|
||||
|
||||
AudioMemFree ( sample );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioSampleInit ( AudioSample *sample )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( sample != NULL );
|
||||
DBG_SET_TYPE ( sample, AudioSample );
|
||||
sample->Data = NULL;
|
||||
sample->Bytes = 0;
|
||||
sample->Format = NULL;
|
||||
sample->Attribs = NULL;
|
||||
ListInit ( &sample->Frames );
|
||||
|
||||
#ifdef _DEBUG
|
||||
sample->name[0] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef IG_FINAL_RELEASE
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioSampleSetName ( AudioSample *sample, const char *orig_name )
|
||||
{
|
||||
int diff;
|
||||
char *buffer = NULL;
|
||||
char *name;
|
||||
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample );
|
||||
|
||||
buffer = (char *) AudioMemAlloc ( strlen ( orig_name ) + 1);
|
||||
name = buffer;
|
||||
sample->name[0] = 0;
|
||||
|
||||
if ( name )
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
strcpy ( name, orig_name );
|
||||
|
||||
ptr = strrchr ( name, '.' );
|
||||
|
||||
if ( ptr )
|
||||
{
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
ptr = strrchr ( name, '\\' );
|
||||
|
||||
if ( ptr )
|
||||
{
|
||||
name = ptr + 1;
|
||||
}
|
||||
|
||||
if ( ( diff = (strlen ( name ) - (sizeof(sample->name) - 1))) > 0 )
|
||||
{
|
||||
strcpy ( sample->name, "...");
|
||||
name = name + diff + 3;
|
||||
strcat ( sample->name, name );
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy ( sample->name, name );
|
||||
}
|
||||
}
|
||||
|
||||
if ( buffer )
|
||||
{
|
||||
AudioMemFree ( buffer );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioSampleAddFrame ( AudioSample *sample, AudioFrame *frame )
|
||||
{
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample );
|
||||
DBG_ASSERT_TYPE ( frame, AudioFrame );
|
||||
|
||||
ListAddToTail ( &sample->Frames, &frame->nd );
|
||||
|
||||
sample->Bytes += frame->Bytes;
|
||||
frame->sample = sample;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
AudioFrame* AudioSampleFirstFrame ( AudioSample *sample )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample );
|
||||
|
||||
return (AudioFrame *) ListNodeNext ( &sample->Frames );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioSampleDeinit ( AudioSample *sample )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( sample, AudioSample );
|
||||
|
||||
DBG_INVALIDATE_TYPE ( sample );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioFormatBytes ( AudioFormat *format, TimeStamp time )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( format, AudioFormat );
|
||||
return (int) ( ((TimeStamp)format->BytesPerSecond*time)/(TimeStamp)SECONDS(1));
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
TimeStamp AudioFormatTime ( AudioFormat *format, int bytes )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( format, AudioFormat );
|
||||
|
||||
if ( format->BytesPerSecond )
|
||||
{
|
||||
return (((TimeStamp)bytes)*(TimeStamp)SECONDS(1))/(TimeStamp)format->BytesPerSecond;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioFormatInit ( AudioFormat *format )
|
||||
{
|
||||
|
||||
DBG_ASSERT ( format != NULL );
|
||||
|
||||
memset ( format, 0, sizeof ( AudioFormat));
|
||||
|
||||
DBG_SET_TYPE ( format, AudioFormat );
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioFormatUpdate ( AudioFormat *format )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( format, AudioFormat );
|
||||
DBG_ASSERT ( format->Channels != 0 );
|
||||
DBG_ASSERT ( format->SampleWidth >0 );
|
||||
DBG_ASSERT ( format->Rate >0 );
|
||||
DBG_ASSERT ( format->Compression < AUDIO_COMPRESS_MAX_ID );
|
||||
|
||||
if ( format->Compression != AUDIO_COMPRESS_MP3 )
|
||||
{
|
||||
format->BytesPerSecond = format->Channels*format->SampleWidth*format->Rate;
|
||||
if ( format->Compression == AUDIO_COMPRESS_IMA_ADPCM
|
||||
|| format->Compression == AUDIO_COMPRESS_MS_ADPCM )
|
||||
{
|
||||
format->BytesPerSecond >>= 2; // 4:1 compression
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int mpeg1 = (W_BitsGet ( format->cdata.mp3.Header, 1, 19 ));
|
||||
int bitrateindex = W_BitsGet ( format->cdata.mp3.Header, 4, 12 );
|
||||
format->BytesPerSecond = bit_rate[mpeg1][bitrateindex] / 8;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioFrameInit ( AudioFrame *frame, void *data, int bytes )
|
||||
{
|
||||
|
||||
DBG_ASSERT_PTR ( frame );
|
||||
|
||||
DBG_SET_TYPE ( frame, AudioFrame );
|
||||
|
||||
frame->Bytes = bytes;
|
||||
frame->Data = data;
|
||||
ListNodeInit ( &frame->nd );
|
||||
frame->sample = NULL;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
void AudioFrameDeinit ( AudioFrame *frame )
|
||||
{
|
||||
|
||||
DBG_ASSERT_TYPE ( frame, AudioFrame );
|
||||
|
||||
frame->sample = NULL;
|
||||
|
||||
DBG_INVALIDATE_TYPE ( frame );
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
#define MAX_SYNC_SEARCH (10*1024) // max bytes that will be searched for the sync
|
||||
|
||||
int AudioFormatReadMP3File ( File *file, AudioFormat *format, int *datasize )
|
||||
{
|
||||
unsigned char buffer[MAX_SYNC_SEARCH+3];
|
||||
int bytes;
|
||||
int pos;
|
||||
unsigned int header = 0;
|
||||
int bitrateindex = 0; // initialize to prevent compiler warning
|
||||
int sampling_frequency = 0; // initialize to prevent compiler warning
|
||||
int layer;
|
||||
|
||||
int data_start = file->position ();
|
||||
|
||||
|
||||
bytes = file->read ( buffer, sizeof (buffer ));
|
||||
|
||||
pos = 0;
|
||||
|
||||
while ( !header && bytes >= 4 )
|
||||
{
|
||||
unsigned char mask = 0xFF;
|
||||
// find next sync
|
||||
while ( bytes >= 3 )
|
||||
{
|
||||
if ( (buffer[pos]&mask) == mask )
|
||||
{
|
||||
if ( mask == 0xE0 )
|
||||
{
|
||||
pos--;
|
||||
bytes++;
|
||||
//header = (buffer[pos] << 24) || (buffer[pos+1] << 16) || (buffer[pos+2] << 8) || buffer[pos+3];
|
||||
header = MAKEID ( buffer[pos], buffer[pos+1], buffer[pos+2], buffer[pos+3]);
|
||||
break;
|
||||
}
|
||||
mask = 0xE0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = 0xFF;
|
||||
}
|
||||
pos++;
|
||||
bytes--;
|
||||
}
|
||||
|
||||
// validate the header
|
||||
bitrateindex = W_BitsGet ( header, 4, 12 );
|
||||
sampling_frequency = W_BitsGet ( header, 2, 10 );
|
||||
layer = (W_BitsGet ( header, 2, 17 ));
|
||||
if ( bitrateindex == 0x0f || sampling_frequency == 0x03 || layer != 1)
|
||||
{
|
||||
header = 0;
|
||||
pos++;
|
||||
bytes--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!header )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int mpeg25 = !(W_BitsGet ( header, 1, 20 ));
|
||||
int mpeg1 = (W_BitsGet ( header, 1, 19 ));
|
||||
int mode = (W_BitsGet ( header, 2, 6 ));
|
||||
|
||||
format->Compression = AUDIO_COMPRESS_MP3;
|
||||
format->SampleWidth = 2;
|
||||
format->Channels = (mode == 3) ? 1 : 2;
|
||||
format->BytesPerSecond = bit_rate[mpeg1][bitrateindex] / 8;
|
||||
format->Rate = sample_rate[mpeg25][mpeg1][sampling_frequency];
|
||||
format->Flags = mAUDIO_FORMAT_PCM;
|
||||
format->cdata.mp3.Header = header;
|
||||
|
||||
AudioFormatUpdate ( format );
|
||||
|
||||
|
||||
if ( datasize )
|
||||
{
|
||||
*datasize = file->size() - (data_start + pos) ;
|
||||
}
|
||||
|
||||
file->seek ( data_start+pos, File::START );
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioFormatSeekToPos ( File *file, const AudioFormat *format, int pos, int data_start )
|
||||
{
|
||||
if ( pos )
|
||||
{
|
||||
int block_size = 0;
|
||||
|
||||
if ( format->Compression == AUDIO_COMPRESS_MP3 )
|
||||
{
|
||||
AudioFormat tformat;
|
||||
file->seek ( pos+data_start, File::START );
|
||||
|
||||
AudioFormatInit ( &tformat );
|
||||
|
||||
int found = FALSE;
|
||||
|
||||
while ( !found )
|
||||
{
|
||||
if ( !AudioFormatReadMP3File ( file, &tformat, NULL ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( AudioFormatSame ( &tformat, format ) )
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
file->seek ( 1, File::CURRENT );
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = file->seek ( 0, File::CURRENT ) - data_start ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch ( format->Compression )
|
||||
{
|
||||
case AUDIO_COMPRESS_NONE:
|
||||
block_size = format->Channels*format->SampleWidth;
|
||||
break;
|
||||
case AUDIO_COMPRESS_IMA_ADPCM:
|
||||
case AUDIO_COMPRESS_MS_ADPCM:
|
||||
block_size = format->cdata.adpcm.BlockSize;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( block_size > 1 )
|
||||
{
|
||||
pos = ( pos / block_size ) *block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file->seek ( pos + data_start, File::START );
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
int AudioFormatSame ( const AudioFormat *f1, const AudioFormat *f2 )
|
||||
{
|
||||
if ( (f1->Rate != f2->Rate )
|
||||
|| (f1->Compression != f2->Compression )
|
||||
|| (f1->SampleWidth != f2->SampleWidth )
|
||||
|| (f1->Channels != f2->Channels )
|
||||
|| (f1->Flags != f2->Flags ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( f1->Compression == AUDIO_COMPRESS_IMA_ADPCM && (f1->cdata.adpcm.BlockSize != f2->cdata.adpcm.BlockSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( f1->Compression == AUDIO_COMPRESS_MP3 && (f1->cdata.mp3.Header != f2->cdata.mp3.Header))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
1307
Generals/Code/Libraries/Source/WPAudio/AUD_StreamBuffering.cpp
Normal file
1307
Generals/Code/Libraries/Source/WPAudio/AUD_StreamBuffering.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1643
Generals/Code/Libraries/Source/WPAudio/AUD_Streamer.cpp
Normal file
1643
Generals/Code/Libraries/Source/WPAudio/AUD_Streamer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
220
Generals/Code/Libraries/Source/WPAudio/AUD_Time.cpp
Normal file
220
Generals/Code/Libraries/Source/WPAudio/AUD_Time.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
** **
|
||||
** Westwood Studios Pacific. **
|
||||
** **
|
||||
** Confidential Information **
|
||||
** Copyright (C) 2000 - All Rights Reserved **
|
||||
** **
|
||||
******************************************************************************
|
||||
** **
|
||||
** Project: Dune Emperor **
|
||||
** **
|
||||
** Module: <module> (<prefix>_) **
|
||||
** **
|
||||
** Version: $ID$ **
|
||||
** **
|
||||
** File name: audtimer.cpp **
|
||||
** **
|
||||
** Created by: 04/??/99 TR **
|
||||
** **
|
||||
** Description: <description> **
|
||||
** **
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Includes **
|
||||
*****************************************************************************/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <wpaudio/time.h>
|
||||
|
||||
/*****************************************************************************
|
||||
** Externals **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Defines **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Types **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Data **
|
||||
*****************************************************************************/
|
||||
|
||||
static TimeStamp lastTime = 0;
|
||||
static TimeStamp interval = 0;
|
||||
static TimeStamp timeOut = 0;
|
||||
static TimeStamp (*timerFunc)( void ) = NULL;// set to either highResGetTime or
|
||||
// failsafeGetTime at initialization
|
||||
static LONGLONG timerMilliSecScale; // res counter millisecond scaling factor
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Data **
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Prototypes **
|
||||
*****************************************************************************/
|
||||
|
||||
static TimeStamp failsafeGetTime( void );
|
||||
static TimeStamp highResGetTime( void );
|
||||
|
||||
/*****************************************************************************
|
||||
** Private Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static TimeStamp highResGetTime( void )
|
||||
{
|
||||
LARGE_INTEGER count;
|
||||
union
|
||||
{
|
||||
TimeStamp timeStamp;
|
||||
LARGE_INTEGER largeInt;
|
||||
}
|
||||
myTime;
|
||||
|
||||
// read the high res counter
|
||||
QueryPerformanceCounter(&count);
|
||||
|
||||
// convert high res ticks to number of milliseconds
|
||||
myTime.largeInt.QuadPart = count.QuadPart / timerMilliSecScale;
|
||||
|
||||
return myTime.timeStamp;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
static TimeStamp failsafeGetTime( void )
|
||||
{
|
||||
static volatile TimeStamp time = (TimeStamp) 0x100000000; // last time value
|
||||
static unsigned int* const pl = (unsigned int* const) &time; // low word of time
|
||||
static unsigned int* const ph = (unsigned int* const) ((unsigned int)&time + 4); // high word of time
|
||||
unsigned int now, lw, hw, called;
|
||||
static volatile unsigned int calls = 0;
|
||||
|
||||
|
||||
calls++;
|
||||
|
||||
retry:
|
||||
|
||||
called = calls;
|
||||
|
||||
hw = *ph; // read high word of time stamp
|
||||
lw = *pl; // read low word of time stamp
|
||||
|
||||
if ( called != calls)
|
||||
{
|
||||
// AudioGetTime() has been re-entered. Cannot trust lw and lh values
|
||||
goto retry;
|
||||
}
|
||||
|
||||
reread:
|
||||
|
||||
now = timeGetTime ();
|
||||
|
||||
if ( now < lw )
|
||||
{
|
||||
// wrap round
|
||||
hw++; // increment high word by one
|
||||
}
|
||||
|
||||
*ph = hw;
|
||||
*pl = now;
|
||||
|
||||
if ( called != calls )
|
||||
{
|
||||
// re-entered. cannot trust *ph and *pl to be correct
|
||||
called = calls;
|
||||
goto reread;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Public Functions **
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
//
|
||||
// Initialize the high resolution timer by querying the system for it's
|
||||
// availability. If one does exist then we set the game timer function
|
||||
// to 'highResGetTime' otherwise we use the original code at 'failsafeGetTime'.
|
||||
// For the hi res counter we precalculate the millisecond scaling factor to
|
||||
// convert hi res ticks to millisecond usage.
|
||||
|
||||
void InitAudioTimer( void )
|
||||
{
|
||||
LARGE_INTEGER freq;
|
||||
|
||||
// does hardware exist for high res counter?
|
||||
if (QueryPerformanceFrequency(&freq))
|
||||
{
|
||||
// calculate timer ticks per second
|
||||
timerMilliSecScale = freq.QuadPart / (LONGLONG) SECONDS(1);
|
||||
|
||||
timerFunc = highResGetTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no high res timer, use old code instead
|
||||
timerFunc = failsafeGetTime;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/******************************************************************/
|
||||
|
||||
TimeStamp AudioGetTime( void )
|
||||
{
|
||||
return timerFunc ? timerFunc() : 0 ;
|
||||
}
|
||||
|
508
Generals/Code/Libraries/Source/WPAudio/AUD_Windows.cpp
Normal file
508
Generals/Code/Libraries/Source/WPAudio/AUD_Windows.cpp
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Westwood Studios Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2001 - All Rights Reserved
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Project: WPAudio
|
||||
//
|
||||
// Module: AUD
|
||||
//
|
||||
// File name: AUD_Windows.cpp
|
||||
//
|
||||
// Created: 5/09/01
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Includes
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmreg.h>
|
||||
|
||||
#include <wpaudio/thread.h>
|
||||
#include <wpaudio/memory.h>
|
||||
#include <wpaudio/Source.h>
|
||||
#include <wsys/File.h>
|
||||
#include <wpaudio/device.h>
|
||||
#include <wpaudio/profiler.h>
|
||||
#include <wpaudio/win32.h>
|
||||
|
||||
// 'assignment within condition expression'.
|
||||
#pragma warning(disable : 4706)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Externals
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Defines
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private Types
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct _aud_thread
|
||||
{
|
||||
char name[200];
|
||||
volatile int quit; /* thread must quit */
|
||||
volatile int count;
|
||||
volatile int leaving; /* thread is quiting */
|
||||
volatile TimeStamp interval; /* itask interval */
|
||||
volatile int running; /* thread is running */
|
||||
HANDLE handle; /* threads handle (windows) */
|
||||
void *data;
|
||||
AUD_ThreadCB *code;
|
||||
DWORD id; /* thread id (windows) */
|
||||
CRITICAL_SECTION access;
|
||||
AudioServiceInfo update;
|
||||
ProfileCPU cpu;
|
||||
|
||||
DBG_TYPE()
|
||||
};
|
||||
|
||||
DBG_DECLARE_TYPE ( AUD_Thread )
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private Data
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Public Data
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static HWND audioMainWindowHandle = NULL;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private Prototypes
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static DWORD WINAPI AUD_service_thread ( VOID *data );
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private Functions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static DWORD WINAPI AUD_service_thread ( VOID *data )
|
||||
{
|
||||
AUD_Thread *thread = (AUD_Thread *) data;
|
||||
|
||||
if ( !thread )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUD_ThreadBeginCriticalSection ( thread );
|
||||
|
||||
thread->running = TRUE;
|
||||
thread->leaving = FALSE;
|
||||
|
||||
while ( !thread->quit )
|
||||
{
|
||||
if ( thread->code ( thread, thread->data ))
|
||||
{
|
||||
AUD_ThreadEndCriticalSection ( thread );
|
||||
Sleep ( (unsigned long ) thread->interval );
|
||||
AUD_ThreadBeginCriticalSection ( thread );
|
||||
}
|
||||
else
|
||||
{
|
||||
AUD_ThreadEndCriticalSection ( thread );
|
||||
Sleep ( MSECONDS(5));
|
||||
AUD_ThreadBeginCriticalSection ( thread );
|
||||
}
|
||||
|
||||
thread->count++;
|
||||
}
|
||||
|
||||
AUD_ThreadEndCriticalSection ( thread );
|
||||
thread->leaving = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Public Functions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
AUD_Thread* AUD_ThreadCreate ( const char *name, AUD_ThreadPriority pri, AUD_ThreadCB *code )
|
||||
{
|
||||
AUD_Thread *thread;
|
||||
|
||||
ALLOC_STRUCT ( thread, AUD_Thread );
|
||||
|
||||
DBG_SET_TYPE ( thread, AUD_Thread );
|
||||
|
||||
if ( !name )
|
||||
{
|
||||
name = "no name given";
|
||||
}
|
||||
|
||||
strncpy ( thread->name, name, ArrayLen(thread->name));
|
||||
ArrayEnd(thread->name);
|
||||
thread->quit = FALSE;
|
||||
thread->leaving = FALSE;
|
||||
thread->running = FALSE;
|
||||
thread->count = 0;
|
||||
thread->code = code;
|
||||
AudioServiceInfoInit ( &thread->update );
|
||||
ProfileCPUInit ( thread->cpu );
|
||||
InitializeCriticalSection ( &thread->access );
|
||||
|
||||
|
||||
AUD_ThreadSetInterval ( thread, SECONDS(1)/30 );
|
||||
|
||||
if ( !(thread->handle = CreateThread ( NULL, 4*1024, AUD_service_thread, thread, 0, &thread->id )))
|
||||
{
|
||||
DBGPRINTF (( "ERROR: Failed to create audio thread: '%s'\n", thread->name ));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int set;
|
||||
|
||||
switch (pri)
|
||||
{
|
||||
case AUD_THREAD_PRI_NORMAL:
|
||||
set = TRUE;
|
||||
break;
|
||||
case AUD_THREAD_PRI_HIGH:
|
||||
set = SetThreadPriority ( thread->handle, THREAD_PRIORITY_HIGHEST );
|
||||
break;
|
||||
case AUD_THREAD_PRI_REALTIME:
|
||||
set = SetThreadPriority ( thread->handle, THREAD_PRIORITY_TIME_CRITICAL );
|
||||
break;
|
||||
default:
|
||||
DBG_MSGASSERT ( FALSE, ("Illegal thread priority"));
|
||||
set = TRUE;
|
||||
}
|
||||
|
||||
if ( !set )
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buffer, sizeof(buffer), NULL);
|
||||
DBGPRINTF (( "Unable to change the priority of the thread - %s\n", buffer ));
|
||||
msg_assert ( FALSE, ( "Unable to change the priority of the thread - %s\n", buffer ));
|
||||
}
|
||||
|
||||
DBGPRINTF (( "Created audio thread: '%s'\n", thread->name ));
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadDestroy
|
||||
//============================================================================
|
||||
|
||||
void AUD_ThreadDestroy ( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
|
||||
thread->quit = TRUE;
|
||||
|
||||
while ( !thread->leaving );
|
||||
|
||||
WaitForSingleObject ( thread->handle, SECONDS(5));
|
||||
CloseHandle ( thread->handle );
|
||||
DeleteCriticalSection ( &thread->access );
|
||||
DBGPRINTF (( "Removed audio thread: '%s'\n", thread->name ));
|
||||
DBG_INVALIDATE_TYPE ( thread );
|
||||
AudioMemFree ( thread );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadBeginCriticalSection
|
||||
//============================================================================
|
||||
|
||||
void AUD_ThreadBeginCriticalSection ( AUD_Thread *thread)
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
EnterCriticalSection ( &thread->access );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadEndCriticalSection
|
||||
//============================================================================
|
||||
|
||||
void AUD_ThreadEndCriticalSection ( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
LeaveCriticalSection ( &thread->access );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadSetData
|
||||
//============================================================================
|
||||
|
||||
void AUD_ThreadSetData ( AUD_Thread *thread, void *data )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
AUD_ThreadBeginCriticalSection ( thread );
|
||||
thread->data = data;
|
||||
AUD_ThreadEndCriticalSection ( thread );
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadSetInterval
|
||||
//============================================================================
|
||||
|
||||
void AUD_ThreadSetInterval ( AUD_Thread *thread, TimeStamp interval )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
AUD_ThreadBeginCriticalSection ( thread );
|
||||
thread->interval = interval;
|
||||
AudioServiceSetInterval ( &thread->update, thread->interval );
|
||||
AudioServiceSetMustServiceInterval ( &thread->update, thread->interval*4 );
|
||||
AudioServiceSetResetInterval ( &thread->update, thread->interval*4 );
|
||||
AUD_ThreadEndCriticalSection ( thread );
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadGetInterval
|
||||
//============================================================================
|
||||
|
||||
TimeStamp AUD_ThreadGetInterval ( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
|
||||
return thread->interval;
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadName
|
||||
//============================================================================
|
||||
|
||||
char* AUD_ThreadName( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
return thread->name;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadCPUProfile
|
||||
//============================================================================
|
||||
|
||||
ProfileCPU* AUD_ThreadCPUProfile( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
return &thread->cpu;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AUD_ThreadAudioServiceInfo
|
||||
//============================================================================
|
||||
|
||||
AudioServiceInfo* AUD_ThreadServiceInfo( AUD_Thread *thread )
|
||||
{
|
||||
DBG_ASSERT_TYPE ( thread, AUD_Thread );
|
||||
return &thread->update;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AudioFormatReadWaveFile
|
||||
//============================================================================
|
||||
|
||||
int AudioFormatReadWaveFile ( File *file, AudioFormat *format, int *bytes )
|
||||
{
|
||||
RIFF_HEADER rh;
|
||||
RIFF_CHUNK chunk;
|
||||
WAVEFORMATEX *wformat = NULL;
|
||||
int got_format = FALSE;
|
||||
int result = FALSE;
|
||||
//int mp3 = FALSE;
|
||||
|
||||
|
||||
DBG_ASSERT_TYPE ( format, AudioFormat );
|
||||
|
||||
|
||||
if ( bytes )
|
||||
{
|
||||
*bytes = 0;
|
||||
}
|
||||
|
||||
if ( !file )
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
file->seek ( 0, File::START );
|
||||
|
||||
/* read wav info */
|
||||
if ( file->read ( &rh, sizeof (rh)) != sizeof(rh) )
|
||||
{
|
||||
DBGPRINTF (( "error: cannot read file\n" ));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( rh.form != vRIFF || rh.type != vWAVE )
|
||||
{
|
||||
file->seek ( 0, File::START );
|
||||
result = AudioFormatReadMP3File ( file, format, bytes );
|
||||
goto done;
|
||||
}
|
||||
|
||||
while ( file->read ( &chunk, sizeof (chunk) ) == sizeof(chunk) )
|
||||
{
|
||||
switch ( chunk.type )
|
||||
{
|
||||
case vFMT :
|
||||
|
||||
if ( chunk.length < sizeof ( WAVEFORMATEX ) )
|
||||
{
|
||||
wformat = (WAVEFORMATEX *) malloc ( sizeof(WAVEFORMATEX));
|
||||
memset ( wformat, 0, sizeof ( WAVEFORMATEX) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wformat = (WAVEFORMATEX *) malloc ( chunk.length );
|
||||
memset ( wformat, 0, chunk.length );
|
||||
}
|
||||
file->read ( wformat, chunk.length );
|
||||
wformat->cbSize = (ushort) chunk.length;
|
||||
got_format = TRUE;
|
||||
break;
|
||||
case vDATA:
|
||||
*bytes = chunk.length;
|
||||
goto got_data;
|
||||
default:
|
||||
file->seek ( chunk.length, File::CURRENT );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBGPRINTF (( "no data chunk found\n" ));
|
||||
|
||||
goto done;
|
||||
|
||||
got_data:
|
||||
|
||||
if ( !wformat )
|
||||
{
|
||||
DBGPRINTF (( "no format chunk found\n" ));
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
format->SampleWidth = wformat->wBitsPerSample / 8;
|
||||
|
||||
if ( wformat->wFormatTag == WAVE_FORMAT_IMA_ADPCM )
|
||||
{
|
||||
format->cdata.adpcm.BlockSize = wformat->nBlockAlign;
|
||||
format->Compression = AUDIO_COMPRESS_IMA_ADPCM;
|
||||
format->SampleWidth = 2;
|
||||
}
|
||||
else if ( wformat->wFormatTag == WAVE_FORMAT_ADPCM )
|
||||
{
|
||||
ADPCMWAVEFORMAT *aformat = (ADPCMWAVEFORMAT *)wformat;
|
||||
|
||||
if ( aformat->wNumCoef != 7 && memcmp ( aformat->aCoef, MSADPCM_StdCoef, sizeof ( MSADPCM_StdCoef )) )
|
||||
{
|
||||
//currently we only support MS ADPCM using the standard coef table
|
||||
goto done;
|
||||
}
|
||||
format->cdata.adpcm.BlockSize = wformat->nBlockAlign;
|
||||
format->Compression = AUDIO_COMPRESS_MS_ADPCM;
|
||||
format->SampleWidth = 2;
|
||||
|
||||
}
|
||||
else if ( wformat->wFormatTag == WAVE_FORMAT_PCM )
|
||||
{
|
||||
format->Compression = AUDIO_COMPRESS_NONE;
|
||||
}
|
||||
else if ( wformat->wFormatTag == WAVE_FORMAT_MPEGLAYER3 )
|
||||
{
|
||||
result = AudioFormatReadMP3File ( file, format, NULL );
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
format->Channels = wformat->nChannels;
|
||||
format->BytesPerSecond = wformat->nAvgBytesPerSec;
|
||||
format->Rate = wformat->nSamplesPerSec;
|
||||
format->Flags = mAUDIO_FORMAT_PCM;
|
||||
|
||||
AudioFormatUpdate ( format );
|
||||
|
||||
result = TRUE;
|
||||
|
||||
done:
|
||||
|
||||
if ( wformat )
|
||||
{
|
||||
free ( wformat );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// WindowsDebugPrint
|
||||
//============================================================================
|
||||
|
||||
void WindowsDebugPrint( const char * lpOutputString )
|
||||
{
|
||||
OutputDebugStringA ( lpOutputString );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AudioSetWindowsHandle
|
||||
//============================================================================
|
||||
|
||||
void AudioSetWindowsHandle ( HWND hwnd )
|
||||
{
|
||||
audioMainWindowHandle = hwnd;
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// AudioGetWindowsHandle
|
||||
//============================================================================
|
||||
|
||||
HWND AudioGetWindowsHandle ( void )
|
||||
{
|
||||
return audioMainWindowHandle;
|
||||
|
||||
}
|
377
Generals/Code/Libraries/Source/WPAudio/WPAudio.dsp
Normal file
377
Generals/Code/Libraries/Source/WPAudio/WPAudio.dsp
Normal file
@@ -0,0 +1,377 @@
|
||||
# Microsoft Developer Studio Project File - Name="WPAudio" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=WPAudio - 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 "WPAudio.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 "WPAudio.mak" CFG="WPAudio - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "WPAudio - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "WPAudio - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "WPAudio - Win32 Internal" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "WPAudio"
|
||||
# PROP Scc_LocalPath "..\.."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "WPAudio - 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 /W3 /WX /GX /O2 /Ob2 /I "..\..\include" /D "_LIB" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_RELEASE" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "WPAudio - 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 /W3 /WX /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "WPAudio - Win32 Internal"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Internal"
|
||||
# PROP BASE Intermediate_Dir "Internal"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Internal"
|
||||
# PROP Intermediate_Dir "Internal"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /WX /GX /O2 /Ob1 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "_INTERNAL" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
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 "WPAudio - Win32 Release"
|
||||
# Name "WPAudio - Win32 Debug"
|
||||
# Name "WPAudio - Win32 Internal"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Assert.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Attributes.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Cache.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Channel.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Device.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_DSoundDriver.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Events.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Level.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_List.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Lock.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Memory.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Profiler.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Source.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_StreamBuffering.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Streamer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Time.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AUD_Windows.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Altypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Attributes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Cache.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Channel.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Debug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Defs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Device.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Driver.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Errors.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Events.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Handle.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Level.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\List.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Lock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Memory.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Profiler.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Search.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Source.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\StreamBuffering.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Streamer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Thread.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Time.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\WPAudio\Win32.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Asimp3"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Asimp3asm.asm
|
||||
|
||||
!IF "$(CFG)" == "WPAudio - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.\Asimp3
|
||||
OutDir=.\Release
|
||||
InputPath=.\Asimp3\Asimp3asm.asm
|
||||
|
||||
BuildCmds= \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /Fo$(OutDir)\asi_x86.obj $(InputPath) \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /DAMD /Fo$(OutDir)\asi_amd.obj $(InputPath) \
|
||||
|
||||
|
||||
"$(OutDir)\asi_x86.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(OutDir)\asi_amd.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "WPAudio - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.\Asimp3
|
||||
OutDir=.\Debug
|
||||
InputPath=.\Asimp3\Asimp3asm.asm
|
||||
|
||||
BuildCmds= \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /Fo$(OutDir)\asi_x86.obj $(InputPath) \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /DAMD /Fo$(OutDir)\asi_amd.obj $(InputPath) \
|
||||
|
||||
|
||||
"$(OutDir)\asi_x86.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(OutDir)\asi_amd.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "WPAudio - Win32 Internal"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.\Asimp3
|
||||
OutDir=.\Internal
|
||||
InputPath=.\Asimp3\Asimp3asm.asm
|
||||
|
||||
BuildCmds= \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /Fo$(OutDir)\asi_x86.obj $(InputPath) \
|
||||
$(InputDir)\bin\ml /nologo /coff /Cp /Zm /c /W2 /Zi /DAMD /Fo$(OutDir)\asi_amd.obj $(InputPath) \
|
||||
|
||||
|
||||
"$(OutDir)\asi_x86.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(OutDir)\asi_amd.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Datatbl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Imssapi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Mp3api.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Mp3dec.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Mp3dec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Mss.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Mssasi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Asimp3\Rib.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
Reference in New Issue
Block a user