// Writes data to a file (synchronous). 
AKRESULT CAkDefaultIOHookBlocking::Write(
    AkFileDesc &			in_fileDesc,        // File descriptor.
    const AkIoHeuristics & /*in_heuristics*/,	// Heuristics for this data transfer (not used in this implementation).
    void *					in_pData,           // Data to be written.
    AkIOTransferInfo &		io_transferInfo		// Synchronous data transfer info. 
    )
{
    AKASSERT(in_pData &&
        in_fileDesc.hFile != INVALID_HANDLE_VALUE);

    OVERLAPPED overlapped;
    overlapped.Offset = (DWORD)(io_transferInfo.uFilePosition & 0xFFFFFFFF);
    overlapped.OffsetHigh = (DWORD)((io_transferInfo.uFilePosition >> 32) & 0xFFFFFFFF);
    overlapped.hEvent = NULL;

    AkUInt32 uSizeTransferred;

    if (::WriteFile(
        in_fileDesc.hFile,
        in_pData,
        io_transferInfo.uRequestedSize,
        &uSizeTransferred,
        &overlapped))
    {
        AKASSERT(uSizeTransferred == io_transferInfo.uRequestedSize);
        return AK_Success;
    }
    return AK_Fail;
}
// Initialization/termination. Init() registers this object as the one and
// only File Location Resolver if none were registered before. Then
// it creates a streaming device with scheduler type AK_SCHEDULER_DEFERRED_LINED_UP.
AKRESULT CAkDefaultIOHookDeferred::Init(
  const AkDeviceSettings 	&in_deviceSettings,		// Device settings.
  bool						in_bAsyncOpen/*=false*/	// If true, files are opened asynchronously when possible.
) {
  if ( in_deviceSettings.uSchedulerTypeFlags != AK_SCHEDULER_DEFERRED_LINED_UP ) {
    AKASSERT( !"CAkDefaultIOHookDeferred I/O hook only works with AK_SCHEDULER_DEFERRED_LINED_UP devices" );
    return AK_Fail;
  }

  m_bAsyncOpen = in_bAsyncOpen;

  // If the Stream Manager's File Location Resolver was not set yet, set this object as the
  // File Location Resolver (this I/O hook is also able to resolve file location).
  if ( !AK::StreamMgr::GetFileLocationResolver() )
    AK::StreamMgr::SetFileLocationResolver( this );

  // Create a device in the Stream Manager, specifying this as the hook.
  m_deviceID = AK::StreamMgr::CreateDevice( in_deviceSettings, this );
  if ( m_deviceID != AK_INVALID_DEVICE_ID ) {
    // Initialize structures needed to perform deferred transfers.
    AkUInt32 uPoolSize = (AkUInt32)( in_deviceSettings.uMaxConcurrentIO * sizeof( OVERLAPPED ) );
    m_poolID = AK::MemoryMgr::CreatePool( NULL, uPoolSize, sizeof( OVERLAPPED ), AkMalloc | AkFixedSizeBlocksMode );
    if ( m_poolID == AK_INVALID_POOL_ID ) {
      AKASSERT( !"Failed creating pool for asynchronous device" );
      return AK_Fail;
    }
    AK_SETPOOLNAME( m_poolID, L"Deferred I/O hook" );

    return AK_Success;
  }

  return AK_Fail;
}
예제 #3
0
// Writes data to a file (asynchronous overload).
AKRESULT CAkDefaultIOHookDeferred::Write(
	AkFileDesc &			in_fileDesc,        // File descriptor.
	const AkIoHeuristics & /*in_heuristics*/,	// Heuristics for this data transfer (not used in this implementation).
	AkAsyncIOTransferInfo & io_transferInfo		// Platform-specific asynchronous IO operation info.
	)
{
	AKASSERT( in_fileDesc.hFile != INVALID_HANDLE_VALUE 
			&& io_transferInfo.uRequestedSize > 0 );

	// If this assert comes up, it might be beacause this hook's GetBlockSize() return value is incompatible 
	// with the system's handling of file reading for this specific file handle.
	// Are you using the File Package Low-Level I/O with incompatible block size? (check -blocksize argument in the File Packager command line)
	AKASSERT( io_transferInfo.uFilePosition % GetBlockSize( in_fileDesc ) == 0
			|| !"Requested file position for I/O transfer is inconsistent with block size" );

	OVERLAPPED * pOverlapped = GetFreeOverlapped( &io_transferInfo );
	
	// Set file offset in OVERLAPPED structure.
	pOverlapped->Offset = (DWORD)( io_transferInfo.uFilePosition & 0xFFFFFFFF );
	pOverlapped->OffsetHigh = (DWORD)( ( io_transferInfo.uFilePosition >> 32 ) & 0xFFFFFFFF );

    // File was open with asynchronous flag. 
    // Read overlapped. 
    if ( ::WriteFileEx( in_fileDesc.hFile,
                      io_transferInfo.pBuffer,
                      io_transferInfo.uRequestedSize,
                      pOverlapped,
					  CAkDefaultIOHookDeferred::FileIOCompletionRoutine ) )
	{
		return AK_Success;
	}
	ReleaseOverlapped( pOverlapped );
    return AK_Fail;
}
예제 #4
0
// Helper: Find a file entry by ID.
const CAkFilePackageLUT::AkFileEntry * CAkFilePackageLUT::LookupFile(
	AkFileID			in_uID,					// File ID.
	const FileLUT *		in_pLut,				// LUT to search.
	bool				in_bIsLanguageSpecific	// True: match language ID.
	)
{
	const AkFileEntry * pTable	= in_pLut->FileEntries();

	AKASSERT( pTable && in_pLut->HasFiles() );
	AkUInt16 uLangID = in_bIsLanguageSpecific ? m_curLangID : AK_INVALID_LANGUAGE_ID;

	// Binary search. LUT items should be sorted by fileID, then by language ID.
	AkInt32 uTop = 0, uBottom = in_pLut->NumFiles()-1;
	do
	{
		AkInt32 uThis = ( uBottom - uTop ) / 2 + uTop; 
		if ( pTable[ uThis ].fileID > in_uID ) 
			uBottom = uThis - 1;
		else if ( pTable[ uThis ].fileID < in_uID ) 
			uTop = uThis + 1;
		else
		{
			// Correct ID. Check language.
			if ( pTable[ uThis ].uLanguageID > uLangID ) 
				uBottom = uThis - 1;
			else if ( pTable[ uThis ].uLanguageID < uLangID ) 
				uTop = uThis + 1;
			else
				return pTable + uThis;
		}
	}
	while ( uTop <= uBottom );

	return NULL;
}
예제 #5
0
AkUInt32 CAkFilePackageLUT::StringMap::GetID( const AkOSChar* in_pszString )
{
	// Make string lower case.
	size_t uStrLen = AKPLATFORM::OsStrLen(in_pszString)+1;
	AkOSChar * pszLowerCaseString = (AkOSChar*)AkAlloca(uStrLen*sizeof(AkOSChar));
	AKASSERT( pszLowerCaseString );
	AKPLATFORM::SafeStrCpy(pszLowerCaseString, in_pszString, uStrLen );
	_MakeLower( pszLowerCaseString );

	// 'this' is m_uNumStrings. +1 points to the beginning of the StringEntry array.
	StringEntry * pTable = (StringEntry*)((AkUInt32*)this + 1);

	// Binary search: strings are sorted (case sensitive).
	AkInt32 uTop = 0, uBottom = m_uNumStrings-1;
	do
	{
		AkInt32 uThis = ( uBottom - uTop ) / 2 + uTop;
		AkOSChar * pString = (AkOSChar*)((AkUInt8*)this + pTable[ uThis ].uOffset);
		int iCmp = AKPLATFORM::OsStrCmp( pString, pszLowerCaseString );
		if ( 0 == iCmp )
			return pTable[uThis].uID;
		else if ( iCmp > 0 )	//in_pTable[ uThis ].pString > pszLowerCaseString
			uBottom = uThis - 1;
		else					//in_pTable[ uThis ].pString < pszLowerCaseString
			uTop = uThis + 1;
	}
	while ( uTop <= uBottom );

	// ID not found.
	return AK_INVALID_UNIQUE_ID;
}
예제 #6
0
AKRESULT CFileIOHandler_wwise::Init(AkDeviceSettings const& rDeviceSettings, bool const bAsyncOpen /* = false */)
{
	AKRESULT eResult = AK_Fail;

	if (rDeviceSettings.uSchedulerTypeFlags == AK_SCHEDULER_BLOCKING)
	{
		m_bAsyncOpen = bAsyncOpen;

		// If the Stream Manager's File Location Resolver was not set yet, set this object as the 
		// File Location Resolver (this I/O hook is also able to resolve file location).
		if (!AK::StreamMgr::GetFileLocationResolver())
		{
			AK::StreamMgr::SetFileLocationResolver(this);
		}

		// Create a device in the Stream Manager, specifying this as the hook.
		m_nDeviceID = AK::StreamMgr::CreateDevice(rDeviceSettings, this);

		if (m_nDeviceID != AK_INVALID_DEVICE_ID)
		{
			eResult = AK_Success;
		}
	}
	else
	{
		AKASSERT(!"CAkDefaultIOHookBlocking I/O hook only works with AK_SCHEDULER_BLOCKING devices");
	}

	return eResult;
}
// Initialization/termination. Init() registers this object as the one and 
// only File Location Resolver if none were registered before. Then 
// it creates a streaming device with scheduler type AK_SCHEDULER_BLOCKING.
AKRESULT CAkDefaultIOHookBlocking::Init(
    const AkDeviceSettings &	in_deviceSettings,		// Device settings.
    bool						in_bAsyncOpen/*=false*/	// If true, files are opened asynchronously when possible.
    )
{
    if (in_deviceSettings.uSchedulerTypeFlags != AK_SCHEDULER_BLOCKING)
    {
        AKASSERT(!"CAkDefaultIOHookBlocking I/O hook only works with AK_SCHEDULER_BLOCKING devices");
        return AK_Fail;
    }

    m_bAsyncOpen = in_bAsyncOpen;

    // If the Stream Manager's File Location Resolver was not set yet, set this object as the 
    // File Location Resolver (this I/O hook is also able to resolve file location).
    if (!AK::StreamMgr::GetFileLocationResolver())
        AK::StreamMgr::SetFileLocationResolver(this);

    // Create a device in the Stream Manager, specifying this as the hook.
    m_deviceID = AK::StreamMgr::CreateDevice(in_deviceSettings, this);
    if (m_deviceID != AK_INVALID_DEVICE_ID)
        return AK_Success;

    return AK_Fail;
}
예제 #8
0
AKRESULT CFileIOHandler_wwise::Write(AkFileDesc& rFileDesc, AkIoHeuristics const& rHeuristics, void* pBuffer, AkIOTransferInfo& rTransferInfo)
{
	AKASSERT(pBuffer != nullptr && rFileDesc.hFile != AkFileHandle(INVALID_HANDLE_VALUE));

	FILE* const pFile = reinterpret_cast<FILE*>(rFileDesc.hFile);
	long const nCurrentFileWritePos	= gEnv->pCryPak->FTell(pFile);
	long const nWantedFileWritePos	= static_cast<long>(rTransferInfo.uFilePosition);

	if (nCurrentFileWritePos != nWantedFileWritePos)
	{
		gEnv->pCryPak->FSeek(pFile, nWantedFileWritePos, SEEK_SET);
	}

	size_t const nBytesWritten = gEnv->pCryPak->FWrite(pBuffer, 1, static_cast<size_t>(rTransferInfo.uRequestedSize), pFile);
	AKASSERT(nBytesWritten == static_cast<size_t>(rTransferInfo.uRequestedSize));

	return (nBytesWritten > 0) ? AK_Success : AK_Fail;
}
예제 #9
0
// Reads data from a file (asynchronous overload).
AKRESULT CAkDefaultIOHookDeferred::Read(
	AkFileDesc &			in_fileDesc,        // File descriptor.
	const AkIoHeuristics & /*in_heuristics*/,	// Heuristics for this data transfer (not used in this implementation).
	AkAsyncIOTransferInfo & io_transferInfo		// Asynchronous data transfer info.
	)
{
	AKASSERT( in_fileDesc.hFile != INVALID_HANDLE_VALUE 
			&& io_transferInfo.uRequestedSize > 0 
			&& io_transferInfo.uBufferSize >= io_transferInfo.uRequestedSize );

	// If this assert comes up, it might be beacause this hook's GetBlockSize() return value is incompatible 
	// with the system's handling of file reading for this specific file handle.
	// If you are using the File Package extension, did you create your package with a compatible
	// block size? It should be a multiple of WIN32_NO_BUFFERING_BLOCK_SIZE. (check -blocksize argument in the File Packager command line)
	AKASSERT( ( io_transferInfo.uFilePosition % WIN32_NO_BUFFERING_BLOCK_SIZE ) == 0
			|| !"Requested file position for I/O transfer is inconsistent with block size" );

	OVERLAPPED * pOverlapped = GetFreeOverlapped( &io_transferInfo );
	
	// Set file offset in OVERLAPPED structure.
	pOverlapped->Offset = (DWORD)( io_transferInfo.uFilePosition & 0xFFFFFFFF );
	pOverlapped->OffsetHigh = (DWORD)( ( io_transferInfo.uFilePosition >> 32 ) & 0xFFFFFFFF );

	// File was open with asynchronous flag. 
    // Read overlapped. 
	// Note: With a file handle opened with FILE_FLAG_NO_BUFFERING, ::ReadFileEx() supports read sizes that go beyond the end
	// of file. However, it does not support read sizes that are not a multiple of the drive's sector size.
	// Since the buffer size is always a multiple of the block size, let's use io_transferInfo.uBufferSize
	// instead of io_transferInfo.uRequestedSize.
    if ( ::ReadFileEx( in_fileDesc.hFile,
                      io_transferInfo.pBuffer,
                      io_transferInfo.uBufferSize,
                      pOverlapped,
					  CAkDefaultIOHookDeferred::FileIOCompletionRoutine ) )
	{
		return AK_Success;
	}
	ReleaseOverlapped( pOverlapped );
    return AK_Fail;
}
// Find a file entry by ID.
const CAkFilePackageLUT::AkFileEntry<AkUInt64> *CAkFilePackageLUT::LookupFile(
  AkUInt64			in_uID,			// File ID.
  AkFileSystemFlags *in_pFlags		// Special flags. Do not pass NULL.
) {
  AKASSERT( in_pFlags );

  if ( in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL
       && m_pExternals
       && m_pExternals->HasFiles() ) {
    return LookupFile<AkUInt64>( in_uID, m_pExternals, in_pFlags->bIsLanguageSpecific );
  }

  // No table loaded.
  return NULL;
}
예제 #11
0
AKRESULT CFileIOHandler_wwise::Close(AkFileDesc& rFileDesc)
{
	AKRESULT eResult = AK_Fail;
	
	if (!gEnv->pCryPak->FClose(reinterpret_cast<FILE*>(rFileDesc.hFile)))
	{
		eResult = AK_Success;
	}
	else
	{
		AKASSERT(!"Failed to close file handle");
	}

	return eResult;
}
// Returns a description for the streaming device above this low-level hook.
void CAkDefaultIOHookBlocking::GetDeviceDesc(
    AkDeviceDesc &
#ifndef AK_OPTIMIZED
    out_deviceDesc      // Description of associated low-level I/O device.
#endif
    )
{
#ifndef AK_OPTIMIZED
    AKASSERT(m_deviceID != AK_INVALID_DEVICE_ID || !"Low-Level device was not initialized");
    out_deviceDesc.deviceID = m_deviceID;
    out_deviceDesc.bCanRead = true;
    out_deviceDesc.bCanWrite = true;
    AKPLATFORM::SafeStrCpy(out_deviceDesc.szDeviceName, WIN32_BLOCKING_DEVICE_NAME, AK_MONITOR_DEVICENAME_MAXLENGTH);
    out_deviceDesc.uStringSize = (AkUInt32)wcslen(out_deviceDesc.szDeviceName) + 1;
#endif
}
// Find a file entry by ID.
const CAkFilePackageLUT::AkFileEntry<AkFileID> *CAkFilePackageLUT::LookupFile(
  AkFileID			in_uID,			// File ID.
  AkFileSystemFlags *in_pFlags		// Special flags. Do not pass NULL.
) {
  AKASSERT( in_pFlags && in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC );

  if ( in_pFlags->uCodecID == AKCODECID_BANK
       && m_pSoundBanks
       && m_pSoundBanks->HasFiles() ) {
    return LookupFile<AkFileID>( in_uID, m_pSoundBanks, in_pFlags->bIsLanguageSpecific );
  } else if ( m_pStmFiles && m_pStmFiles->HasFiles() ) {
    // We assume that the file is a streamed audio file.
    return LookupFile<AkFileID>( in_uID, m_pStmFiles, in_pFlags->bIsLanguageSpecific );
  }
  // No table loaded.
  return NULL;
}
AKRESULT CAkDefaultLowLevelIODispatcher::AddDevice(
	AK::StreamMgr::IAkFileLocationResolver *	in_pHook
	)
{
	// Add the device in a free slot.
	for ( AkUInt32 uRecord = 0; uRecord < AK_MAX_IO_DEVICES; uRecord++ )
	{
		if ( !m_arDevices[uRecord] )
		{
			m_arDevices[uRecord] = in_pHook;
			++m_uNumDevices;
			return AK_Success;
		}
	}
	AKASSERT( !"Cannot hold any more I/O devices" );
	return AK_Fail;
}
예제 #15
0
AKRESULT s3eIOHook::Init(const AkDeviceSettings &in_deviceSettings)
{
	if ( in_deviceSettings.uSchedulerTypeFlags != AK_SCHEDULER_BLOCKING )
	{
		AKASSERT( !"s3eIOHook I/O hook only works with AK_SCHEDULER_BLOCKING devices" );
		return AK_Fail;
	}

	// If the Stream Manager's File Location Resolver was not set yet, set this object as the
	// File Location Resolver (this I/O hook is also able to resolve file location).
	if ( !AK::StreamMgr::GetFileLocationResolver() )
		AK::StreamMgr::SetFileLocationResolver( this );

	// Create a device in the Stream Manager, specifying this as the hook.
	m_deviceID = AK::StreamMgr::CreateDevice( in_deviceSettings, this );
	if ( m_deviceID != AK_INVALID_DEVICE_ID )
		return AK_Success;

	return AK_Fail;
}
예제 #16
0
AKRESULT s3eIOHook::Open(const AkOSChar* in_pszFileName, AkOpenMode in_eOpenMode, AkFileSystemFlags *in_pFlags, bool &io_bSyncOpen, AkFileDesc &out_fileDesc)
{
	io_bSyncOpen = true;

    const char *mode;
    switch ( in_eOpenMode )
	{
		case AK_OpenModeRead:
			mode = "r";
			break;
		case AK_OpenModeWrite:
			mode = "w";
			break;
		case AK_OpenModeWriteOvrwr:
			mode = "w+";
			break;
		case AK_OpenModeReadWrite:
			mode = "a";
			break;
		default:
			AKASSERT( !"Invalid open mode" );
			return AK_InvalidParameter;
			break;
	}

    s3eFile *file = s3eFileOpen(in_pszFileName, mode);

	if ( file != NULL )
	{
		out_fileDesc.iFileSize			= s3eFileGetSize(file);
		out_fileDesc.uSector			= 0;
		out_fileDesc.deviceID			= m_deviceID;
		out_fileDesc.pCustomParam		= NULL;
		out_fileDesc.uCustomParamSize	= 0;
        out_fileDesc.hFile              = (AkFileHandle)file;

        return AK_Success;
	}

	return AK_Fail;
}
// Local callback for overlapped I/O.
VOID CALLBACK CAkDefaultIOHookDeferred::FileIOCompletionRoutine(
  DWORD dwErrorCode,
  DWORD
#ifdef _DEBUG
  dwNumberOfBytesTransfered
#endif
  ,
  LPOVERLAPPED lpOverlapped
) {
  AkAsyncIOTransferInfo *pXferInfo = (AkAsyncIOTransferInfo *)(lpOverlapped->hEvent);

  ReleaseOverlapped( lpOverlapped );

  AKRESULT eResult = AK_Fail;
  if ( ERROR_SUCCESS == dwErrorCode ) {
    eResult = AK_Success;
    AKASSERT( dwNumberOfBytesTransfered >= pXferInfo->uRequestedSize && dwNumberOfBytesTransfered <= pXferInfo->uBufferSize );
  }

  pXferInfo->pCallback( pXferInfo, eResult );
}
// Returns a file descriptor for a given file ID.
AKRESULT CAkDefaultLowLevelIODispatcher::Open( 
    AkFileID        in_fileID,          // File ID.
    AkOpenMode      in_eOpenMode,       // Open mode.
    AkFileSystemFlags * in_pFlags,      // Special flags. Can pass NULL.
	bool &			io_bSyncOpen,		// If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
    AkFileDesc &    out_fileDesc        // Returned file descriptor.
    )
{
    // Here, you need to define a strategy to determine which device is going to handle this file's I/O.
	// You could use the AkFileSystemFlags if it depends on file type, or define a map, or read the mapping 
	// from an XML file... it is up to the game's organization.
	// Since this default implementation doesn't know anything about that, it forwards the calls to each 
	// device until one of them succeeds. 

	// Disable deferred opening because devices may usually return AK_Success if io_bSyncOpen=false,
	// and we count on the fact that they will return AK_Fail to select the proper device.
	io_bSyncOpen = true;
    
	AKRESULT eResult = AK_FileNotFound;
	AkUInt32 uDevice = 0;
	while ( uDevice < AK_MAX_IO_DEVICES
			&& eResult != AK_Success )
	{
		if ( m_arDevices[uDevice] )
		{
			eResult = m_arDevices[uDevice]->Open( 
				in_fileID,          // File ID.
				in_eOpenMode,       // Open mode.
				in_pFlags,			// Special flags. Can pass NULL.
				io_bSyncOpen,		// If true, the file must be opened synchronously. Otherwise it is left at the File Location Resolver's discretion. Return false if Open needs to be deferred.
				out_fileDesc        // Returned file descriptor.
				);
			AKASSERT( io_bSyncOpen || !"It is illegal to reset io_bSyncOpen" );
		}
		++uDevice;
	}

	return eResult; 
}
// ID overload. 
// The name of the file will be formatted as ID.ext. This is meant to be used with options
// "Use SoundBank Names" unchecked, and/or "Copy Streamed Files" in the SoundBank Settings.
// For more details, refer to the SoundBank Settings in Wwise Help, and to section "Identifying Banks" inside
// "Sound Engine Integration Walkthrough > Integrate Wwise Elements into Your Game > Integrating Banks > 
// Integration Details - Banks > General Information" of the SDK documentation.
// Returns AK_Success if input flags are supported and the resulting path is not too long.
// Returns AK_Fail otherwise.
AKRESULT CAkFileLocationBase::GetFullFilePath(
	AkFileID			in_fileID,			// File ID.
	AkFileSystemFlags *	in_pFlags,			// Special flags. 
	AkOpenMode			/* in_eOpenMode*/,	// File open mode (read, write, ...).
	AkOSChar *			out_pszFullFilePath	// Full file path.
	)
{
    // If the file descriptor could not be found, or if the script-based FS does not exist,
    // map file ID to file descriptor (string based) for Audiokinetic IDs.
	
	if ( !in_pFlags ||
         !(in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC || in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL))
	{
		AKASSERT( !"Unhandled file type" );
		return AK_Fail;
	}

	// Compute file name with file system paths.
	size_t uiPathSize = AKPLATFORM::OsStrLen( m_szBasePath );
	
	// Copy base path. 
	AKPLATFORM::SafeStrCpy( out_pszFullFilePath, m_szBasePath, AK_MAX_PATH );
	// Concatenate path for AK banks or streamed audio files (everything except banks).
	if ( in_pFlags->uCodecID == AKCODECID_BANK )
	{
		uiPathSize += AKPLATFORM::OsStrLen( m_szBankPath );
		if ( uiPathSize >= AK_MAX_PATH )
		{
			AKASSERT( !"Path is too large" );
			return AK_Fail;
		}
		AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szBankPath, AK_MAX_PATH );
	}
	else
	{
		uiPathSize += AKPLATFORM::OsStrLen( m_szAudioSrcPath );
		if ( uiPathSize >= AK_MAX_PATH )
		{
			AKASSERT( !"Path is too large" );
			return AK_Fail;
		}
		AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szAudioSrcPath, AK_MAX_PATH );
	}

	// Externally supplied source (see External Sources in SDK doc)
	// In this sample, we will assume that the file to load when receiving an external FileID is 
	// simply the FileID.wem (e.g. "12345.wem").  If you use the External Source feature
	// you should modify this section to handle your FileIDs properly.
	/*if (in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL)
	{
		
	}*/
	
	// Add language directory name if needed.
	if ( in_pFlags->bIsLanguageSpecific )
	{
		size_t uLanguageStrLen = AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() );
		if ( uLanguageStrLen > 0 )
		{
			uiPathSize += ( uLanguageStrLen + 1 );
			if ( uiPathSize >= AK_MAX_PATH )
			{
				AKASSERT( !"Path is too large" );
				return AK_Fail;
			}
			AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK::StreamMgr::GetCurrentLanguage(), AK_MAX_PATH );
			AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK_PATH_SEPARATOR, AK_MAX_PATH );
		}
	}
	
	// Append file title.
	if ( ( uiPathSize + MAX_FILETITLE_SIZE ) <= AK_MAX_PATH )
	{
		AkOSChar * pszTitle = out_pszFullFilePath + uiPathSize;
		if ( in_pFlags->uCodecID == AKCODECID_BANK )
			AK_OSPRINTF( pszTitle, MAX_FILETITLE_SIZE, ID_TO_STRING_FORMAT_BANK, (unsigned int)in_fileID );
		else
			AK_OSPRINTF( pszTitle, MAX_FILETITLE_SIZE, ID_TO_STRING_FORMAT_WEM, (unsigned int)in_fileID );
	}
	else
	{
		AKASSERT( !"String buffer too small" );
		return AK_Fail;
	}
	
	return AK_Success;
}
예제 #20
0
AKRESULT CFileIOHandler_wwise::Open(AkOSChar const* sFileName, AkOpenMode eOpenMode, AkFileSystemFlags* pFlags, bool& rSyncOpen, AkFileDesc& rFileDesc)
{
	AKRESULT eResult = AK_Fail;

	if (rSyncOpen || !m_bAsyncOpen)
	{
		rSyncOpen = true;
		AkOSChar sFinalFilePath[AK_MAX_PATH] = {'\0'};
		AKPLATFORM::SafeStrCat(sFinalFilePath, m_sBankPath, AK_MAX_PATH);

		if (pFlags != nullptr && eOpenMode == AK_OpenModeRead)
		{
			// Add language folder if the file is localized.
			if (pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC && pFlags->uCodecID == AKCODECID_BANK && pFlags->bIsLanguageSpecific)
			{
				AKPLATFORM::SafeStrCat(sFinalFilePath, m_sLanguageFolder, AK_MAX_PATH);
			}
		}

		AKPLATFORM::SafeStrCat(sFinalFilePath, sFileName, AK_MAX_PATH);

		char* sTemp = nullptr;
		CONVERT_OSCHAR_TO_CHAR(sFinalFilePath, sTemp);
		char const* sOpenMode = nullptr;

		switch (eOpenMode)
		{
		case AK_OpenModeRead:
			{
				sOpenMode = "rbx";

				break;
			}
		case AK_OpenModeWrite:
			{
				sOpenMode = "wbx";

				break;
			}
		case AK_OpenModeWriteOvrwr:
			{
				sOpenMode = "w+bx";

				break;
			}
		case AK_OpenModeReadWrite:
			{
				sOpenMode = "abx";

				break;
			}
		default:
			{
				AKASSERT(!"Unknown file open mode!");

				break;
			}
		}

		FILE* const pFile = gEnv->pCryPak->FOpen(sTemp, sOpenMode, ICryPak::FOPEN_HINT_DIRECT_OPERATION);

		if (pFile != nullptr)
		{
			rFileDesc.iFileSize					= static_cast<AkInt64>(gEnv->pCryPak->FGetSize(sTemp));
			rFileDesc.hFile							= GetFileHandle(pFile);
			rFileDesc.uSector						= 0;
			rFileDesc.deviceID					= m_nDeviceID;
			rFileDesc.pCustomParam			= nullptr;
			rFileDesc.uCustomParamSize	= 0;

			eResult = AK_Success;
		}
	}

	return eResult;
}
// String overload.
// Returns AK_Success if input flags are supported and the resulting path is not too long.
// Returns AK_Fail otherwise.
AKRESULT CAkFileLocationBase::GetFullFilePath(
	const AkOSChar*		in_pszFileName,		// File name.
	AkFileSystemFlags * in_pFlags,			// Special flags. Can be NULL.
	AkOpenMode			in_eOpenMode,		// File open mode (read, write, ...).
	AkOSChar*			out_pszFullFilePath // Full file path.
	)
{
    if ( !in_pszFileName )
    {
        AKASSERT( !"Invalid file name" );
        return AK_InvalidParameter;
    }

	// Prepend string path (basic file system logic).

    // Compute file name with file system paths.
	size_t uiPathSize = AKPLATFORM::OsStrLen( in_pszFileName );

    if ( uiPathSize >= AK_MAX_PATH )
	{
		AKASSERT( !"Input string too large" );
		return AK_InvalidParameter;
	}

#ifdef AK_WIN
	// MP3 files using the MP3 sample code, usually being provided by the gamer will 
	// not be located in the game path, for these sounds, we are using the Full path
	// to access them.
	if ( in_pFlags != NULL && 
		 in_pFlags->uCodecID == AKSOURCEID_MP3 &&
		 in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC )
	{
		out_pszFullFilePath[0] = 0;
	}
	else
#endif
	{
		AKPLATFORM::SafeStrCpy( out_pszFullFilePath, m_szBasePath, AK_MAX_PATH );
	}

    if ( in_pFlags 
		&& in_eOpenMode == AK_OpenModeRead )
    {
        // Add bank path if file is an AK sound bank.
        if ( in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC &&
             in_pFlags->uCodecID == AKCODECID_BANK )
		{
			uiPathSize += AKPLATFORM::OsStrLen( m_szBankPath );
			if ( uiPathSize >= AK_MAX_PATH )
			{
				AKASSERT( !"Path is too large" );
				return AK_Fail;        
			}
			AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szBankPath, AK_MAX_PATH );
		}
		
		// Note: Standard streaming files do not use this overload. On the other hand, streaming external 
		// sources use it if you use AkExternalSourceInfo::szFile instead of AkExternalSourceInfo::idFile.		

		// Externally supplied source (see External Sources in SDK doc)
		// In this sample, we will assume that the external source file name in_pszFileName
		// must be used as is (e.g. "myExternalSourceFile.wem").  If you use the External Source feature
		// you should modify this section to handle your FileIDs properly.
		/*if (in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL)
		{
			
		}*/
		
		// Add language directory name if needed.
		if ( in_pFlags->bIsLanguageSpecific )
		{
			size_t uLanguageStrLen = AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() );
			if ( uLanguageStrLen > 0 )
			{
				uiPathSize += ( uLanguageStrLen + 1 );
				if ( uiPathSize >= AK_MAX_PATH )
				{
					AKASSERT( !"Path is too large" );
					return AK_Fail;
				}
				AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK::StreamMgr::GetCurrentLanguage(), AK_MAX_PATH );
				AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK_PATH_SEPARATOR, AK_MAX_PATH );
			}
		}
	}
        
    // Append file title.
	uiPathSize += AKPLATFORM::OsStrLen( out_pszFullFilePath );
	if ( uiPathSize >= AK_MAX_PATH )
	{
		AKASSERT( !"File name string too large" );
		return AK_Fail;
	}
	AKPLATFORM::SafeStrCat( out_pszFullFilePath, in_pszFileName, AK_MAX_PATH );
	return AK_Success;
}
예제 #22
0
	AKRESULT Init( 
		AkMemSettings *     in_pMemSettings,
		AkStreamMgrSettings * in_pStmSettings,
		AkDeviceSettings *  in_pDefaultDeviceSettings,
		AkInitSettings *    in_pSettings,
		AkPlatformInitSettings * in_pPlatformSettings,
		AkMusicSettings *	in_pMusicSettings
		)
	{
		// Check required arguments.
		if ( !in_pMemSettings ||
			 !in_pStmSettings ||
			 !in_pDefaultDeviceSettings )
		{
			AKASSERT( !"Invalid arguments" );
			return AK_InvalidParameter;
		}

		// Create and initialise an instance of our memory manager.
		if ( AK::MemoryMgr::Init( in_pMemSettings ) != AK_Success )
		{
			AKASSERT( !"Could not create the memory manager." );
			return AK_Fail;
		}

		// Create and initialise an instance of the default stream manager.
		if ( !AK::StreamMgr::Create( *in_pStmSettings ) )
		{
			AKASSERT( !"Could not create the Stream Manager" );
			return AK_Fail;
		}

		// Create an IO device.
#ifdef AK_ANDROID
		if (g_assetManager == NULL)
		{
			AKASSERT( !"Could not find Android asset manager" );
			return AK_Fail;
		}

		g_lowLevelIO.SetAssetManager(g_assetManager);
#endif 

		if ( g_lowLevelIO.Init( *in_pDefaultDeviceSettings ) != AK_Success )
		{
			AKASSERT( !"Cannot create streaming I/O device" );
			return AK_Fail;
		}

#ifdef AK_ANDROID
		in_pPlatformSettings->pJavaVM = java_vm;
#endif

#ifdef AK_IOS
		in_pPlatformSettings->bAppListensToInterruption = true;
#endif // #ifdef AK_IOS
		// Initialize sound engine.
		if (  AK::SoundEngine::Init( in_pSettings, in_pPlatformSettings ) != AK_Success )
		{
			AKASSERT( !"Cannot initialize sound engine" );
			return AK_Fail;
		}

		// Initialize music engine.
		if ( AK::MusicEngine::Init( in_pMusicSettings ) != AK_Success )
		{
			AKASSERT( !"Cannot initialize music engine" );
			return AK_Fail;
		}

#ifndef AK_OPTIMIZED
	#ifndef AK_METRO
		// Initialize communication.
		AkCommSettings settingsComm;
		AK::Comm::GetDefaultInitSettings( settingsComm );
		if ( AK::Comm::Init( settingsComm ) != AK_Success )
		{
			AKASSERT( !"Cannot initialize music communication" );
		}
	#endif // #ifndef AK_METRO
#endif // AK_OPTIMIZED
		
		// Register plugins
		if ( AK::SoundEngine::RegisterAllPlugins( ) != AK_Success )
		{
			AKASSERT( !"Error while registering plug-ins" );
			return AK_Fail;
		}

		return AK_Success;
	}