1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  3. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  4. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  5. Dismiss Notice
  6. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

Soundtrack Pack in Progress

Discussion in 'Civ4 - Caveman 2 Cosmos' started by Praetyre, Nov 8, 2011.

  1. Praetyre

    Praetyre Chieftain

    Joined:
    Nov 19, 2009
    Messages:
    893
    Gender:
    Male
    Location:
    Auckland, New Zealand
    I've PMed this to a couple of folks, but I figured it'd be easier just to have an open inquiry about these issues, so there ya go:

    I have compiled an extremely large collection of mp3 files which offers well over 200 new tracks for all eras, categorized and folderized be era. There are a grand total of 277 files, but some of these are existing tracks that I have either retained or repurposed. The chief issue is not the size, however; I'm sure that the file could simply be hosted here as a seperate download (it's around 1.11 GB in total) and split into 100-150 MB segments by era if there's enough demand for it.

    The main issue is how to get it into the game. It would be extremely impractical to actually put all 200+ tracks into the 2Ds audio files, and I'd rather not put a heavy load on an xml team already overburdened with the goods-resource conversion project. There is the custom music folder option, but I don't know if that can distinguish between era, and even if it could, could it distinguish between the new eras C2C adds?

    As such, I'm putting this out there for those who have any ideas as to handle the situation. I'm no expert on xml files, but I like to think I have more experience in musical taste. But without a way to get it in, it's a moot point.
     
  2. Thunderbrd

    Thunderbrd C2C War Dog

    Joined:
    Jan 2, 2010
    Messages:
    18,516
    Gender:
    Male
    Location:
    Las Vegas
    That should be easy... package the download so that all we have to do is drop it in our C2C mod file and select to overwrite everything that creates a conflict.

    Aside from that, I'm not sure without looking exactly which files control the track references, but I don't think it'd be hard to find and manipulate with a text editor.
     
  3. Praetyre

    Praetyre Chieftain

    Joined:
    Nov 19, 2009
    Messages:
    893
    Gender:
    Male
    Location:
    Auckland, New Zealand
    The issue isn't conflicts between files; that is indeed easily overwritten. The issue is how to get particular tracks in the game and for them to *only* play in particular eras. Say, all tracks in Folder X must only play in Prehistoric, all tracks in Folder Y must only play in Ancient, Folder Z is for Classical and so on. There are categorizations like this in both the vanilla CivIv and C2C soundtrack, but I'm not sure whether they have any actual function (meaning that putting tracks in, say, the folder "modern" automatically means that track will play during the modern era) or are merely there for administrative purposes.
     
  4. Hydromancerx

    Hydromancerx C2C Modder

    Joined:
    Feb 27, 2008
    Messages:
    16,203
    Location:
    California, USA
    If you can get this to work it sound like an awesome add-on pack for C2C.
     
  5. Thunderbrd

    Thunderbrd C2C War Dog

    Joined:
    Jan 2, 2010
    Messages:
    18,516
    Gender:
    Male
    Location:
    Las Vegas
    Yeah, there are xml controls on the sound references... I'm not sure how to work all that but I don't think it'd be very hard to figure out. If I had time today I'd sort it out and let you know how to go about it but I've gotta go to work :p
     
  6. AIAndy

    AIAndy Chieftain

    Joined:
    Jun 8, 2011
    Messages:
    3,334
    Unfortunately it seems like the audio XML files are loaded in the exe and not the dll.
    So we can't just enumerate files in directories and load them as if they were in the XML.

    This means you have to change these files:
    AudioDefines.xml
    Audio2dScripts.xml
    CIV4EraInfos.xml

    Probably only the last of these is usable as module.
    Since this is extremely repetetive work, I would suggest to write a small script that automatically creates those files.

    The era info should not be overwritten though but instead only the soundtracks redefined in a module.
     
  7. Praetyre

    Praetyre Chieftain

    Joined:
    Nov 19, 2009
    Messages:
    893
    Gender:
    Male
    Location:
    Auckland, New Zealand
    Who's our resident scripter? I'm afraid my knowledge of the matter is rivalled only by my knowledge of Anasazi culture and medieval Polish history.
     
  8. Thunderbrd

    Thunderbrd C2C War Dog

    Joined:
    Jan 2, 2010
    Messages:
    18,516
    Gender:
    Male
    Location:
    Las Vegas
  9. Praetyre

    Praetyre Chieftain

    Joined:
    Nov 19, 2009
    Messages:
    893
    Gender:
    Male
    Location:
    Auckland, New Zealand
    I'll take it then that there isn't currently a dedicated scripter on hand? Might have to outsource it, then...
     
  10. AIAndy

    AIAndy Chieftain

    Joined:
    Jun 8, 2011
    Messages:
    3,334
    My time is quite limited at the moment so if you find someone else that would be good.
    If not, then tell me by the beginning of next week and I'll try to squeeze it in before the beginning of my 2 week holiday at the end of the week.
     
  11. AIAndy

    AIAndy Chieftain

    Joined:
    Jun 8, 2011
    Messages:
    3,334
    With the audio update script present now, any plan to release that, Praetyre?
     
  12. Micael

    Micael Chieftain

    Joined:
    Jul 20, 2010
    Messages:
    89
    Example perl script I just whipped up (I've been working on file processing stuff all week so it all sprang to mind):

    Code:
    
    package QuickXMLTagGeneratingScript;
    
    use strict;
    use warnings;
    
    my $era= "Ancient Era"; # << Whatever the XML expects.
    my $dir = "PATH TO ANCIENT ERA MP3s";
    my @files = <$dir/*>;
    
    # Open up a temporary output files, create if needed.
    # This will just store the XML tags for now.
    open FILEONE, "+<", "C:\\File1.txt";
    open FILETWO, "+<", "C:\\File2.txt";
    open FILETHREE, "+<", "C:\\File3.txt";
    
    # For the length of files array
    foreach my $i (0 .. (@files - 1)) {
    
    # If the file ends in .mp3
    if ($files[$i] =~ /^.+.mp3$/) {
    
    # Print in whatever format the XML Expects it, adds a new line to the end:
    print FILEONE ("\<OPEN TAG\> $files($i) \<\\CLOSE TAG\>\n");
    print FILETWO ("\<OPEN TAG\> $era, $files($i) \<\\CLOSE TAG\>\n");
    print FILETHREE ("\<OPEN TAG\> WHATEVER DATA GOES IN AUDIO SCRIPTS 2D \<\\CLOSE TAG\>\n");
    
    } # Ends if file is mp3.
    } # Ends for all files.
    
    print "(@files) processed. Hit enter to continue.\n";
    <STDIN>;
    Just change the print output format to whatever the XML expects and then you can just do it quick and nasty with this script. It's not as smart as the script you guys were talking about, but you only have to copy/paste it from there. I assume you already know which sounds you want in different eras.

    Obviously, this script won't work as is (it may not work at all, really don't know the civ4 xml structure), but if its helpful for you to use after slight tweaking, then feel free to use it :).

    - Micael
     
  13. AIAndy

    AIAndy Chieftain

    Joined:
    Jun 8, 2011
    Messages:
    3,334
    @Micael: I have since then included a similar functionality as a Python script in C2C. You load/start a game in C2C and it runs and includes all files in specific folders (the EraName New folders in the soundtrack folder) as music files for the era. In addition it changes the title music to a random file in the Title folder.

    It works by editing the XML files so the changes are active the next time you load the game:
    Spoiler :
    Code:
    ## MusicUpdate
    ##
    ## Adds music files in special directories to the respective sound registration files.
    ##
    ## Chooses a random file in a specific directory as title music
    ##
    
    import BugUtil
    import BugPath
    import os
    import os.path
    import random
    import re
    import shutil
    import string
    
    def init():
    	BugUtil.debug("MusicUpdate INIT.")
    
    	soundtrackFolder = BugPath.getModDir() + '/Assets/Sounds/Soundtrack/'
    	audioXMLFolder = BugPath.getModDir() + '/Assets/XML/Audio/'
    	titleFolder = soundtrackFolder + '/Title/'
    	
    	eraNames = [ "Prehistoric", "Ancient", "Classical", "Medieval", "Renaissance", "Industrial", "Modern", "Transhuman", "Galactic", "Future" ]
    	
    	defineFilename = audioXMLFolder + 'AudioDefines.xml'
    	scriptsFilename = audioXMLFolder + 'Audio2DScripts.xml'
    	eraInfoFilename = BugPath.getModDir() + '/Assets/XML/GameInfo/CIV4EraInfos.xml'
    	
    	titleFilenames = os.listdir(titleFolder)
    	titleFile = random.choice(titleFilenames)
    	titleFile = os.path.splitext(titleFile)[0]
    	
    	f = open(defineFilename, "r")
    	content = f.read()
    	f.close()
    	content = re.sub(r'(<SoundID>SONG_OPENING_MENU</SoundID>\s*<Filename>)[^<]*',r'\1Sounds/Soundtrack/Title/'+titleFile,content)	
    	f = open(defineFilename, "w")
    	f.write(content)
    	f.close()
    	
    	f = open(eraInfoFilename, 'r')
    	infoFileContent = f.read()
    	f.close()
    	
    	toInsertDef = ""
    	toInsertScript = ""
    	
    	for era in eraNames:
    		eraFolder = soundtrackFolder + era
    		eraNewFolder = eraFolder + 'New'
    		newFiles = os.listdir(eraNewFolder)
    		if newFiles:
    			toInsert = ""
    			for newFile in newFiles:
    				if os.path.isdir(eraNewFolder + '/' + newFile):
    					continue
    				shutil.move(eraNewFolder + '/' + newFile, eraFolder + '/' + newFile)
    				fileTag = os.path.splitext(newFile)[0]
    				fileTagUpper = string.upper(fileTag)
    				fileTagUpper = re.sub(r'\s', r'_', fileTagUpper)
    				fileTagUpper = re.sub(r'[^A-Z0-9_]', r'', fileTagUpper)
    				toInsert = toInsert + "\n<EraInfoSoundtrack>AS2D_"+fileTagUpper+"</EraInfoSoundtrack>"
    				toInsertDef = toInsertDef + "<SoundData>\n<SoundID>SONG_"+fileTagUpper+"</SoundID>\n<Filename>Sounds/Soundtrack/"+era+"/"+fileTag+"</Filename>\n<LoadType>STREAMED</LoadType>\n<bIsCompressed>1</bIsCompressed>\n<bInGeneric>1</bInGeneric>\n</SoundData>\n"
    				toInsertScript = toInsertScript + "<Script2DSound>\n<ScriptID>AS2D_"+fileTagUpper+"</ScriptID>\n<SoundID>SONG_"+fileTagUpper+"</SoundID>\n<SoundType>GAME_MUSIC</SoundType>\n<iMinVolume>80</iMinVolume>\n<iMaxVolume>80</iMaxVolume>\n<iPitchChangeDown>0</iPitchChangeDown>\n<iPitchChangeUp>0</iPitchChangeUp>\n<iMinLeftPan>-1</iMinLeftPan>\n<iMaxLeftPan>-1</iMaxLeftPan>\n<iMinRightPan>-1</iMinRightPan>\n<iMaxRightPan>-1</iMaxRightPan>\n<bLooping>0</bLooping>\n<iMinTimeDelay>0</iMinTimeDelay>\n<iMaxTimeDelay>0</iMaxTimeDelay>\n<bTaperForSoundtracks>0</bTaperForSoundtracks>\n<iLengthOfSound>0</iLengthOfSound>\n<fMinDryLevel>1.0</fMinDryLevel>\n<fMaxDryLevel>1.0</fMaxDryLevel>\n<fMinWetLevel>0.0</fMinWetLevel>\n<fMaxWetLevel>0.0</fMaxWetLevel>\n<iNotPlayPercent>0</iNotPlayPercent>\n</Script2DSound>\n"
    			if toInsert:
    				infoFileContent = re.sub(r'(\<Type\>ERA_'+string.upper(era)+r'(?:.|\n)*?\<EraInfoSoundtracks\>)', r'\1'+toInsert, infoFileContent)
    	
    	f = open(eraInfoFilename, 'w')
    	f.write(infoFileContent)
    	f.close()
    		
    	if toInsertDef:
    		f = open(defineFilename, 'r')
    		content = f.read()
    		f.close()
    		content = re.sub(r'(\</SoundDatas\>)', toInsertDef+r'\1', content)
    		f = open(defineFilename, 'w')
    		f.write(content)
    		f.close()
    		
    		f = open(scriptsFilename, 'r')
    		content = f.read()
    		f.close()
    		content = re.sub(r'(\</Script2DSounds\>)', toInsertScript+r'\1', content)
    		f = open(scriptsFilename, 'w')
    		f.write(content)
    		f.close()
     
  14. Micael

    Micael Chieftain

    Joined:
    Jul 20, 2010
    Messages:
    89
    Cool.

    - Micael
     

Share This Page