Files
GTASource/rage/base/tools/audio/InstrumentNoteMapGenerator/InstrumentNoteMapGenerator.cs
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

256 lines
7.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using rage.Generator;
using rage.ToolLib;
namespace rage
{
class Note : IComparable
{
public int tone;
public string waveName;
public Note(string waveName)
{
this.waveName = waveName;
// past the last _ we have the note id - e.g.: HONKYTONK_XX
string noteIndex = waveName.Substring(waveName.LastIndexOf("_") + 1);
this.tone = int.Parse(noteIndex);
}
public int CompareTo(Object note)
{
if (note == null)
{
return 1;
}
else
{
return this.tone.CompareTo(((Note)note).tone);
}
}
override public string ToString()
{
return waveName;
}
}
class NoteRange
{
Note baseNote;
public int firstToneId;
public int lastToneId;
private int releaseTime = 333;
public NoteRange(Note note, int firstToneId, int lastToneId)
{
baseNote = note;
this.firstToneId = firstToneId;
this.lastToneId = lastToneId;
}
public XElement AsSimpleSound(string instrumentName, string instrumentTypeName)
{
XElement simpleSound = new XElement("SimpleSound");
simpleSound.SetAttributeValue("name", instrumentTypeName + "_" + instrumentName + "_" + baseNote.waveName);
simpleSound.SetAttributeValue("folder", instrumentTypeName + "_" + instrumentName + "_COMPONENTS");
XElement waveRef = new XElement("WaveRef");
XElement waveName = new XElement("WaveName", baseNote.waveName);
XElement bankName = new XElement("BankName", "SCRIPT\\" + instrumentName);
XElement release = new XElement("ReleaseTime", releaseTime);
waveRef.Add(waveName);
waveRef.Add(bankName);
simpleSound.Add(waveRef);
simpleSound.Add(release);
return simpleSound;
}
public XElement AsNoteRange(string instrumentName, string instrumentTypeName)
{
XElement rangeKey = new XElement("Range");
XElement firstNoteIdElement = new XElement("FirstNoteId");
firstNoteIdElement.SetValue(firstToneId);
rangeKey.Add(firstNoteIdElement);
XElement lastNoteIdElement = new XElement("LastNoteId");
lastNoteIdElement.SetValue(lastToneId);
rangeKey.Add(lastNoteIdElement);
XElement mode = new XElement("Mode");
mode.SetValue("NOTE_RANGE_TRACK_PITCH");
rangeKey.Add(mode);
XElement soundRef = new XElement("SoundRef");
soundRef.SetValue(instrumentTypeName + "_" + instrumentName + "_" + baseNote.waveName);
rangeKey.Add(soundRef);
return rangeKey;
}
override public string ToString()
{
return baseNote.ToString(); ;
}
}
class Instrument
{
List<Note> notes;
List<NoteRange> noteRanges;
string name;
string type;
public Instrument(string instrumentName, string instrumentTypeName)
{
notes = new List<Note>();
noteRanges = new List<NoteRange>();
name = instrumentName;
type = instrumentTypeName;
}
public void AddNote(Note note)
{
notes.Add(note);
}
public void GenerateAndSortNoteRange()
{
notes.Sort();
int lastFirstToneId = 128;
notes.Reverse();
foreach (Note note in notes)
{
NoteRange newNoteRange = new NoteRange(note, note.tone, lastFirstToneId);
lastFirstToneId = newNoteRange.firstToneId - 1;
noteRanges.Add(newNoteRange);
}
noteRanges.Reverse();
NoteRange firstRange = noteRanges.First<NoteRange>();
firstRange.firstToneId = 0;
}
public List<XElement> AsXML()
{
List<XElement> elements = new List<XElement>();
foreach (NoteRange range in noteRanges)
{
elements.Add(range.AsSimpleSound(name, type));
}
XElement currentNoteMap = new XElement("NoteMap");
currentNoteMap.SetAttributeValue("name", name + "_NoteMap");
foreach (NoteRange range in noteRanges)
{
currentNoteMap.Add(range.AsNoteRange(name, type));
}
elements.Add(currentNoteMap);
return elements;
}
override public string ToString()
{
return name + "_" + type;
}
}
public class InstrumentNoteMapGenerator : IGenerator
{
#region IGenerator Members
public bool Init(rage.ToolLib.Logging.ILog log, string workingPath, rage.audProjectSettings projectSettings, Types.ITypeDefinitionsManager typeDefManager, params string[] args)
{
return true;
}
public XDocument Generate(rage.ToolLib.Logging.ILog log, XDocument inputDoc)
{
var outputDoc = new XDocument();
XElement objsElem = new XElement("Objects");
List<Instrument> instruments = new List<Instrument>();
foreach (XElement packRoot in inputDoc.Descendants("Pack"))
{
foreach (XElement firstLevelElement in packRoot.Descendants("BankFolder"))
{
string baseBankFolderName = firstLevelElement.Attribute("name").Value;
if (baseBankFolderName.ToUpper().Equals("INSTRUMENTS"))
{
foreach (XElement secondLevelElement in firstLevelElement.Descendants("BankFolder"))
{
string instrumentTypeName = secondLevelElement.Attribute("name").Value;
instrumentTypeName = instrumentTypeName.ToUpper();
foreach (XElement instrumentBank in secondLevelElement.Descendants("Bank"))
{
string instrumentName = instrumentBank.Attribute("name").Value;
instrumentName = instrumentName.ToUpper();
Instrument newInstrument = new Instrument(instrumentName, instrumentTypeName);
foreach (XElement waveElement in instrumentBank.Descendants("Wave"))
{
string soundName = waveElement.Attribute("builtName").Value;
soundName = soundName.Substring(0, soundName.Length - 4); // remove the extension
soundName = soundName.ToUpper();
Note newNote = new Note(soundName);
newInstrument.AddNote(newNote);
}
instruments.Add(newInstrument);
}
}
}
}
}
foreach (Instrument instrument in instruments)
{
instrument.GenerateAndSortNoteRange();
List<XElement> elements = instrument.AsXML();
objsElem.Add(elements.ToArray());
}
outputDoc.Add(objsElem);
return outputDoc;
}
public void Shutdown()
{
}
#endregion
}
}