Audiokinetic Wwise Knowledge Base

Migrating your Low-Level I/O to Wwise 2008.4 from earlier versions

The Low-Level I/O API has changed thoroughly between Wwise 2008.3 and 2008.4. This document will help you migrate your implementation.

There are 3 things you can do:
1) If you were using the default Low-Level I/O sample as-is, use the new implementation. See section "Switching to the New Default Low-Level I/O Sample".
2) If you had customized your implementation of the Low-Level I/O system, and were happy with it, you may prefer to continue using the old Stream Manager. See section "Keeping the Old Stream Manager".
3) Otherwise, migrate to the new system. Read section "Migrating to the New Low-Level I/O system".


Switching to the New Default Low-Level I/O Sample

If you were using the default Low-Level I/O sample (CAkDefaultLowLevelIO or CAkFilePackageLowLevelIO), simply use the new default sample.
1) Remove all the obsolete Low-Level I/O files from your project.
2) Include the following files in your project:
 - samples/SoundEngine/$(Platform)/AkDefaultIOHookBlocking.h|cpp
 - samples/SoundEngine/$(Platform)/AkFileHelpers.h
 - samples/SoundEngine/$(Platform)/AkFilePackageLowLevelIOBlocking.h (only if you use file packages)
 - samples/SoundEngine/Common/AkFileLocationBase.h|cpp
 - samples/SoundEngine/Common/AkFileHelpers.h
 - samples/SoundEngine/Common/AkFilePackageLowLevelIO.h|inl (only if you use file packages)
 - samples/SoundEngine/Common/AkFilePackage.h|cpp (only if you use file packages)
 - samples/SoundEngine/Common/AkFilePackageLUT.h|cpp (only if you use file packages)
3) In your code, instantiate a CAkDefaultIOHookBlocking object instead of a CAkDefaultLowLevelIO (or a CAkFilePackageLowLevelIOBlocking instead of a CAkFilePackageLowLevelIO).
4) Update the initialization and termination of the Stream Manager and Low-Level I/O (check the example code in Initializing the Streaming Manager under Wwise SDK 2008.4 - Windows ยป Sound Engine Integration Walkthrough in the SDK's documentation).


Using the Old Stream Manager

The Stream Manager's interface (defined in IAkStreamMgr.h) almost did not change between 2008.3 and 2008.4. If you like, you may keep the old implementation of the Stream Manager and leave your Low-Level I/O implementation as it is now. Note however that the old implementation is no longer maintained nor supported, and you won't benefit from the various optimizations and improved flexibility of the new implementation.

There was one change in the high-level interface. An argument was added in AK::IAkStreamMgr::Create[Std|Auto](): in_bSyncOpen. In order to link properly with the other libraries of the Wwise 2008.4 sound engine, you need to edit the implementation and rebuild it:
1) Get the old stream manager's source code and solutions (source/StreamManager/), delete the whole source/StreamManager/ directory tree of Wwise SDK 2008.4 and replace it with the old one.
2) Restore the old Low-Level I/O interface: delete include/AK/SoundEngine/Common/AkStreamMgrModule.h, and restore include/AK/SoundEngine/Common/AkStreamMgrModule.h and include/AK/SoundEngine/Platforms/$(Platform)/AkStreamMgrModule.h of the previous version.
3) Build the Stream Manager's solution (source/StreamManager/$(Platform)/AkStreamMgr$(Platform).sln). It should fail because of the new argument in CreateStd() and CreateAuto():
 AkStreamMgr.cpp(81) : error C2259: 'AK::CAkStreamMgr' : cannot instantiate abstract class due to following members:
 'AKRESULT AK::IAkStreamMgr::CreateStd(AkFileID,AkFileSystemFlags *,AkOpenMode,AK::IAkStdStream *&,bool)' : is abstract
 ...
4) Edit the prototype of CreateStd() (2 functions) and CreateAuto() (2 functions) in AkStreamMgr.h and AkStreamMgr.cpp: add argument "bool in_bSyncOpen" and ignore it in the implementation.
5) Re-build. Now you got your patched Stream Manager.


Migrating to the New Low-Level I/O system

To upgrade to the new API, you may either start from the sample code, or directly adapt your implementation to the new interface. Refer to section "Switching to the New Default Low-Level I/O Sample" above for the equivalent default implementation files.

As you can see, there are a more interfaces and more sample files than before. There is not more code though, because the API is essentially the same. It was just split apart.
- The Open() methods were moved to an interface called IAkFileLocationResolver. This interface is registered to the Stream Manager through AK::StreamMgr::SetFileLocationResolver(). Otherwise, the prototype of Open() is essentially the same as before.
- The Read() and Write() methods have different prototypes depending on if they are used with an AK_SCHEDULER_BLOCKING or an AK_SCHEDULER_DEFERRED_LINED_UP device. They are defined in both IAkIOHookBlocking and IAkIOHookDeferred. You need to implement one of these 2 interfaces, depending on the type of device you are using. Typically you should use IAkIOHookBlocking. The arguments of Read() and Write() have changed, but they basically carry the same information as their former definition. The main difference is that there is no native, platform-specific structures anymore.
- Both IAkIOHookBlocking and IAkIOHookDeferred derive from IAkLowLevelIOHook, which define Close(), GetBlockSize() and GetDeviceDesc(). You need to implement these as well. Their migration should be pretty straightforward.
- Samples: Filename string computations were moved in the platform-independent object CAkFileLocationBase.
- Samples: File package handling is now implemented through template class CAkFilePackageLowLevelIO. This layer is now platform-independent and supports loading multiple file packages at a time. Note that the File Package format (and thus the CAkFilePackageLUT implementation) was not changed. Refer to the SDK documentation for more information.

Things to look at with greater attention:
- The low-level I/O interface is now platform-independent. If your implementation is a layer above your own platform-independent file system, make it platform-independent!
- Read() and Write() should return AK_Success now, not AK_DataReady or AK_NoMoreData. Returning AK_DataReady is interpreted as "transfer failed".
- In Read() (or in your callback, in a deferred setup), be careful to return the number of bytes that was read. AkIOTransferInfo::uSizeTransferred must be set to the proper value.
- There is no AkIOTransferInfo::bIsSequential flag anymore. File accesses are not always sequential, therefore you cannot rely on the fact that the file position from which to read has not changed since last read. Seek to the proper location in the file prior to calling read. Alternatively, you may use one of the user fields (like AkFileDesc::uCustomParamSize for example) to store the previous read position and determine whether you need to seek or not. You must always specify the position with asynchronous reads (IAkIOHookDeferred).
- The new interface allows you to defer file opening. In order to have your implementation work like before, be sure to set io_bSyncOpen to true in both IAkFileLocationResolver::Open() functions. If you don't do that, your files will probably be opened twice, and handles will leak.
- The configuration-specific GetDeviceDesc() function is in the middle of the vtable. To avoid any inconsistency, be sure to define AK_OPTIMIZED on your side only when linking with Release libraries, not with Debug and Profile libraries.
- If your setup uses more than one device, you should read the documentation thoroughly to learn how you can manage multiple devices, using an IAkFileLocationResolver as a dispatcher.




Article Details

Last Updated
3rd o December, 2008

Would you like to...

Print this page Print this page

Email this page Email this page

Post a comment Post a comment

Subscribe me

Add to favorites Add to favorites

Remove Highlighting Remove Highlighting

Edit this Article

Quick Edit

Export to PDF

User Opinions (2 votes)

100% thumbs up 0% thumbs down

How would you rate this answer?



Thank you for rating this answer.

Related Articles

No related articles were found.

Attachments

No attachments were found.

Continue