BTL4 Has its own AudioRenderer (BTL4AudioRenderer) which just establishes a new AudioHead (BTL4AudioHead).  

MungaL4 has its own AudioRenderer (L4AudioRenderer) which implements the Initialize() function to load world sound info from a file.  It also initializes the AudioHardware.  Finally, it refers to L4AudioResourceManager::PreloadResources.

L4AudioRenderer also! Will create entity audio objects when it is notified of new interesting things.  An audio representation of the object is obtained from entity::GetAudioRepresentation and used to create the necessary entity audio objects in L4AudioResourceManager::CreateEntityAudioObjects.  L4AudioResourceManager::DestroyEntityAudioObjects is used to get rid of it when it’s over.

L4AudioRenderer::StartRequest(L4AudioSource) is called to start an audiosource rendering.  It requests the necessary resources with RequestAudioResources.  If they don’t exist, it will put sustained audio sources in line to play later on when the resources are available.  Otherwise, it will set necessary values and call L4AudioSource::StartImplementation(), which probably checks the type of the audio source and plays it accordingly.  It also adds the source to the running socket and if it isn’t mixed manually, adds it to the mix socket.

L4AudioRenderer::RequestAudioResources(source, channel_set_result) ensures that the source ought to be played (isn’t clipped) and then sends a list of possible channels and number of channels the source will use.  If not enough channels remain, then the list of desired channels is searched for playing audio that has lower importance than the requesting source.  If room can be found, returns true, otherwise false.

L4AudioRenderer::StopRequest(L4AudioSource) checks if the source is suspended or dormant (or otherwise not running) and if so, removes it from the dormant plug (waiting list) and sets it to stop.  For currently-playing sounds, AudioSourceStopMaintenance(source) is called.

L4AudioRenderer::AudioSourceStopMaintenance(source) calls source::StopImplementation(), releases channels, and removes the source from the mix & running sockets.

L4AudioRenderer::AudioSourceSuspendMaintenance(source) calls source::SuspendImplementation(), removes it from the sockets and adds it to the dormant socket.

L4AudioRenderer::ExecuteImplementation() is the renderer-specific code that is called each frame.  It extends AudioRenderer’s implementation.  It mixes stuff in the mix plug, plays stuff in the running plug, and processes stuff in the dormant plug to see if it should activate.

CalculateMix(), RunningSourceCheckup(), and DormantSourceCheckup() perform these activities.

AudioRenderer links its AudioHead when it is linked to a guy.  In ExecuteImplementation (called each frame), AudioRenderer calls Execute() on its AudioHead.  

What does AudioRenderer::PostAudioRequestMessage do?

AudioRenderer::ProcessAudioRequestMessage seems to do something with these requests.  Just calls the Process() function on them if there’s one on the stack.

AudioRenderer::FlushAudioMessages(source) gets rid of any pending audio events for a particular source, only processing messages saying to stop the sound.

AudioRenderer::StartEntityEffectImplementation starts a new sound on a portion of an entity?  AudioEntity::Make is used.

AudioEntity/AudioSource for implementing buffers & sources?
AudioHead for implementing listener controls.

Stuff is held in audio\static.scp!  This is read as a NotationFile

AudioControlSequence seems to be the primary audio/midi file class.  BuildFromPage is used to load the information.  Actually, AudioControlSequence is descended from AudioComponent which seems to be a sort of generic audio class.  I might be able to change the way it loads, stores, and plays its data and have that do most of the work.

AudioControlSequence::BuildFromPage makes use of the CreateAudioControlEventStream class to parse midi files and DynamicMemoryStream objects to hold most information.  

What's a NameList, is it like a string/string dictionary?

In BuildFromPage, we pull the midi_file value from the passed-in NameLIst, open up a file stream, and write it into a DynamicMemoryStream object.  We also pull the tempo from the NameList.  Then we run the file through the midi parser, getting a new DynamicMemoryStream out.

The new DynamicMemoryStream has information on what are apparently called control events- presumably the whole what happens in this midi file info.  We write that as well as a ton of other options into a PlugStream that got passed in as an argument.

Actually, there are a ton of different audio object types, and all of their BuildFromPage things are called from AudioObjectStream::BuildFromPageImplementation.  This seems to be called from a generic ObjectStream::ParseNotationFile(), which may be called fro ObjectStream::BuildFromNotationFile() and ObjectStream::ReadIncludedFiles().  ReadIncludedFiles() is run because a notation file may reference other notation files within it and cause those to be read as well.

BuildFromNotationFile is called from:
	-L4AudioResourceManager::CreateStaticAudioStreamResource(ResourceFile)
	-L4AudioResourceManager::CreateModelAudioStreamResource(ResourceFile, model_name, model_File, ResourceDirectorie)
	-Registry::CreateStaticObjectStreamResource(NotationFile, ResourceFile)

ApplicationTool::BuildResources calls each of these when necessary.  CreateStaticAudioStreamResource may only be called once?

Called from main of BTL4Tool/RPL4Tool.  Where the fuck in the game app?

In WinMain, we open a StreamableResourceFile (btl4.res in BT410).  Also, we make a new BTL4Application object and send in the StreamableResourceFile.

Passes to L4Application to Application.

Saves resourcefile to Application::resourceFile.  Retrievable with GetResourceFile().  Sent to Application::MakeMission() which is picked up by BTL4Application/RPL4Application and used to Create a new BTL4Mission/RPL4Mission.

The mission constructors seem to have the relevant info within.