示例#1
0
        public AudioEngine(string settingsFile)
        {
            if (String.IsNullOrEmpty(settingsFile))
            {
                throw new ArgumentNullException("settingsFile");
            }

            using (Stream stream = TitleContainer.OpenStream(settingsFile))
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    // Check the file header. Should be 'XGSF'
                    if (reader.ReadUInt32() != 0x46534758)
                    {
                        throw new ArgumentException("XGSF format not recognized!");
                    }

                    // Check the Content and Tool versions
                    if (reader.ReadUInt16() != ContentVersion)
                    {
                        throw new ArgumentException("XGSF Content version!");
                    }
                    if (reader.ReadUInt16() != 42)
                    {
                        throw new ArgumentException("XGSF Tool version!");
                    }

                    // Unknown value
                    reader.ReadUInt16();

                    // Last Modified, Unused
                    reader.ReadUInt64();

                    // XACT Version, Unused
                    reader.ReadByte();

                    // Number of AudioCategories
                    ushort numCategories = reader.ReadUInt16();

                    // Number of XACT Variables
                    ushort numVariables = reader.ReadUInt16();

                    // KEY#1 Length
                    /*ushort numKeyOne =*/ reader.ReadUInt16();

                    // KEY#2 Length
                    /*ushort numKeyTwo =*/ reader.ReadUInt16();

                    // Number of RPC Variables
                    ushort numRPCs = reader.ReadUInt16();

                    // Number of DSP Presets/Parameters
                    ushort numDSPPresets    = reader.ReadUInt16();
                    ushort numDSPParameters = reader.ReadUInt16();

                    // Category Offset in XGS File
                    uint categoryOffset = reader.ReadUInt32();

                    // Variable Offset in XGS File
                    uint variableOffset = reader.ReadUInt32();

                    // KEY#1 Offset
                    /*uint keyOneOffset =*/ reader.ReadUInt32();

                    // Category Name Index Offset, unused
                    reader.ReadUInt32();

                    // KEY#2 Offset
                    /*uint keyTwoOffset =*/ reader.ReadUInt32();

                    // Variable Name Index Offset, unused
                    reader.ReadUInt32();

                    // Category Name Offset in XGS File
                    uint categoryNameOffset = reader.ReadUInt32();

                    // Variable Name Offset in XGS File
                    uint variableNameOffset = reader.ReadUInt32();

                    // RPC Variable Offset in XGS File
                    uint rpcOffset = reader.ReadUInt32();

                    // DSP Preset/Parameter Offsets in XGS File
                    uint dspPresetOffset    = reader.ReadUInt32();
                    uint dspParameterOffset = reader.ReadUInt32();

                    /* Unknown table #1
                     * reader.BaseStream.Seek(keyOneOffset, SeekOrigin.Begin);
                     * for (int i = 0; i < numKeyOne; i += 1)
                     * {
                     *      // Appears to consistently be 16 shorts?
                     *      System.Console.WriteLine(reader.ReadInt16());
                     * }
                     * /* OhGodNo
                     *  1, -1,  4, -1,
                     *  3, -1, -1,  7,
                     * -1,  2,  5, -1,
                     *  6,  0, -1, -1
                     *
                     * Naddachance
                     *  1, -1,  4, -1,
                     *  5, -1, -1, -1,
                     * -1,  2, -1, -1,
                     *  3,  0, -1, -1
                     *
                     * TFA
                     *  1, -1, -1, -1,
                     * -1, -1, -1, -1,
                     * -1,  2, -1, -1,
                     * -1, -0, -1, -1
                     */

                    /* Unknown table #2
                     * reader.BaseStream.Seek(keyTwoOffset, SeekOrigin.Begin);
                     * for (int i = 0; i < numKeyTwo; i += 1)
                     * {
                     *      // Appears to be between 16-20 shorts?
                     *      System.Console.WriteLine(reader.ReadInt16());
                     * }
                     * /* OhGodNo
                     *  2,  7,  1, -1,
                     * -1, 10, 19, -1,
                     *  11, 3, -1, -1,
                     *  8, -1, 14,  5,
                     * 12,  0,  4,  6
                     *
                     * Naddachance
                     *  2,  3, -1, -1,
                     *  9, -1,  7, -1,
                     * 10,  0,  1,  5,
                     * -1, -1, -1, -1
                     *
                     * TFA
                     *  2,  3, -1, -1,
                     * -1, -1, -1, -1,
                     * -1,  0,  1,  5,
                     * -1, -1, -1, -1
                     */

                    // Obtain the Audio Category Names
                    reader.BaseStream.Seek(categoryNameOffset, SeekOrigin.Begin);
                    string[] categoryNames = new string[numCategories];
                    for (int i = 0; i < numCategories; i += 1)
                    {
                        List <char> builtString = new List <char>();
                        while (reader.PeekChar() != 0)
                        {
                            builtString.Add(reader.ReadChar());
                        }
                        reader.ReadChar();                 // Null terminator
                        categoryNames[i] = new string(builtString.ToArray());
                    }

                    // Obtain the Audio Categories
                    reader.BaseStream.Seek(categoryOffset, SeekOrigin.Begin);
                    INTERNAL_categories = new List <AudioCategory>();
                    for (int i = 0; i < numCategories; i += 1)
                    {
                        // Maximum instances
                        byte maxInstances = reader.ReadByte();

                        // Fade In/Out
                        ushort fadeInMS  = reader.ReadUInt16();
                        ushort fadeOutMS = reader.ReadUInt16();

                        // Instance Behavior Flags
                        byte instanceFlags = reader.ReadByte();
                        int  fadeType      = instanceFlags & 0x07;
                        int  maxBehavior   = instanceFlags >> 3;

                        // Parent Category
                        short parent = reader.ReadInt16();

                        // Volume
                        float volume = XACTCalculator.CalculateAmplitudeRatio(
                            XACTCalculator.ParseDecibel(
                                reader.ReadByte()
                                )
                            );

                        // Visibility Flags, unused
                        reader.ReadByte();

                        // Add to the engine list and the parent category
                        INTERNAL_categories.Add(
                            new AudioCategory(
                                categoryNames[i],
                                volume,
                                maxInstances,
                                maxBehavior,
                                fadeInMS,
                                fadeOutMS,
                                fadeType
                                )
                            );
                        if (parent != -1)
                        {
                            INTERNAL_categories[parent].subCategories.Add(
                                INTERNAL_categories[i]
                                );
                        }
                    }

                    // Obtain the Variable Names
                    reader.BaseStream.Seek(variableNameOffset, SeekOrigin.Begin);
                    string[] variableNames = new string[numVariables];
                    for (int i = 0; i < numVariables; i += 1)
                    {
                        List <char> builtString = new List <char>();
                        while (reader.PeekChar() != 0)
                        {
                            builtString.Add(reader.ReadChar());
                        }
                        reader.ReadChar();                 // Null terminator
                        variableNames[i] = new string(builtString.ToArray());
                    }

                    // Obtain the Variables
                    reader.BaseStream.Seek(variableOffset, SeekOrigin.Begin);
                    INTERNAL_variables = new List <Variable>();
                    for (int i = 0; i < numVariables; i += 1)
                    {
                        // Variable Accessibility (See Variable constructor)
                        byte varFlags = reader.ReadByte();

                        // Variable Value, Boundaries
                        float initialValue = reader.ReadSingle();
                        float minValue     = reader.ReadSingle();
                        float maxValue     = reader.ReadSingle();

                        // Add to the engine list
                        INTERNAL_variables.Add(
                            new Variable(
                                variableNames[i],
                                (varFlags & 0x01) != 0,
                                (varFlags & 0x02) != 0,
                                (varFlags & 0x04) == 0,
                                (varFlags & 0x08) != 0,
                                initialValue,
                                minValue,
                                maxValue
                                )
                            );
                    }

                    // Obtain the RPC Curves
                    reader.BaseStream.Seek(rpcOffset, SeekOrigin.Begin);
                    INTERNAL_RPCs = new Dictionary <long, RPC>();
                    for (int i = 0; i < numRPCs; i += 1)
                    {
                        // RPC "Code", used by the SoundBanks
                        long rpcCode = reader.BaseStream.Position;

                        // RPC Variable
                        ushort rpcVariable = reader.ReadUInt16();

                        // Number of RPC Curve Points
                        byte numPoints = reader.ReadByte();

                        // RPC Parameter
                        ushort rpcParameter = reader.ReadUInt16();

                        // RPC Curve Points
                        RPCPoint[] rpcPoints = new RPCPoint[numPoints];
                        for (byte j = 0; j < numPoints; j += 1)
                        {
                            float x    = reader.ReadSingle();
                            float y    = reader.ReadSingle();
                            byte  type = reader.ReadByte();
                            rpcPoints[j] = new RPCPoint(
                                x, y,
                                (RPCPointType)type
                                );
                        }

                        // Add to the engine list
                        INTERNAL_RPCs.Add(
                            rpcCode,
                            new RPC(
                                INTERNAL_variables[rpcVariable].Name,
                                rpcParameter,
                                rpcPoints
                                )
                            );
                    }

                    // Obtain the DSP Parameters
                    reader.BaseStream.Seek(dspParameterOffset, SeekOrigin.Begin);
                    INTERNAL_dspParameters = new List <DSPParameter>();
                    for (int i = 0; i < numDSPParameters; i += 1)
                    {
                        // Effect Parameter Type
                        byte type = reader.ReadByte();

                        // Effect value, boundaries
                        float value  = reader.ReadSingle();
                        float minVal = reader.ReadSingle();
                        float maxVal = reader.ReadSingle();

                        // Unknown value
                        reader.ReadUInt16();

                        // Add to Parameter list
                        INTERNAL_dspParameters.Add(
                            new DSPParameter(
                                type,
                                value,
                                minVal,
                                maxVal
                                )
                            );
                    }

                    // Obtain the DSP Presets
                    reader.BaseStream.Seek(dspPresetOffset, SeekOrigin.Begin);
                    INTERNAL_dspPresets = new Dictionary <long, DSPPreset>();
                    int total = 0;
                    for (int i = 0; i < numDSPPresets; i += 1)
                    {
                        // DSP "Code", used by the SoundBanks
                        long dspCode = reader.BaseStream.Position;

                        // Preset Accessibility
                        bool global = (reader.ReadByte() == 1);

                        // Number of preset parameters
                        uint numParams = reader.ReadUInt32();

                        // Obtain DSP Parameters
                        DSPParameter[] parameters = new DSPParameter[numParams];
                        for (uint j = 0; j < numParams; j += 1)
                        {
                            parameters[j] = INTERNAL_dspParameters[total];
                            total        += 1;
                        }

                        // Add to DSP Preset list
                        INTERNAL_dspPresets.Add(
                            dspCode,
                            new DSPPreset(
                                global,
                                parameters
                                )
                            );
                    }
                }

            // Create the WaveBank Dictionary
            INTERNAL_waveBanks = new Dictionary <string, WaveBank>();

            // Finally.
            IsDisposed = false;
        }
示例#2
0
		public AudioEngine(string settingsFile)
		{
			if (String.IsNullOrEmpty(settingsFile))
			{
				throw new ArgumentNullException("settingsFile");
			}

			using (Stream stream = TitleContainer.OpenStream(settingsFile))
			using (BinaryReader reader = new BinaryReader(stream))
			{
				// Check the file header. Should be 'XGSF'
				if (reader.ReadUInt32() != 0x46534758)
				{
					throw new ArgumentException("XGSF format not recognized!");
				}

				// Check the Content and Tool versions
				if (reader.ReadUInt16() != ContentVersion)
				{
					throw new ArgumentException("XGSF Content version!");
				}
				if (reader.ReadUInt16() != 42)
				{
					throw new ArgumentException("XGSF Tool version!");
				}

				// Unknown value
				reader.ReadUInt16();

				// Last Modified, Unused
				reader.ReadUInt64();

				// XACT Version, Unused
				reader.ReadByte();

				// Number of AudioCategories
				ushort numCategories = reader.ReadUInt16();

				// Number of XACT Variables
				ushort numVariables = reader.ReadUInt16();

				// KEY#1 Length
				/*ushort numKeyOne =*/ reader.ReadUInt16();

				// KEY#2 Length
				/*ushort numKeyTwo =*/ reader.ReadUInt16();

				// Number of RPC Variables
				ushort numRPCs = reader.ReadUInt16();

				// Number of DSP Presets/Parameters
				ushort numDSPPresets = reader.ReadUInt16();
				ushort numDSPParameters = reader.ReadUInt16();

				// Category Offset in XGS File
				uint categoryOffset = reader.ReadUInt32();

				// Variable Offset in XGS File
				uint variableOffset = reader.ReadUInt32();

				// KEY#1 Offset
				/*uint keyOneOffset =*/ reader.ReadUInt32();

				// Category Name Index Offset, unused
				reader.ReadUInt32();

				// KEY#2 Offset
				/*uint keyTwoOffset =*/ reader.ReadUInt32();

				// Variable Name Index Offset, unused
				reader.ReadUInt32();

				// Category Name Offset in XGS File
				uint categoryNameOffset = reader.ReadUInt32();

				// Variable Name Offset in XGS File
				uint variableNameOffset = reader.ReadUInt32();

				// RPC Variable Offset in XGS File
				uint rpcOffset = reader.ReadUInt32();

				// DSP Preset/Parameter Offsets in XGS File
				uint dspPresetOffset = reader.ReadUInt32();
				uint dspParameterOffset = reader.ReadUInt32();

				/* Unknown table #1
				reader.BaseStream.Seek(keyOneOffset, SeekOrigin.Begin);
				for (int i = 0; i < numKeyOne; i += 1)
				{
					// Appears to consistently be 16 shorts?
					System.Console.WriteLine(reader.ReadInt16());
				}
				/* OhGodNo
				 *  1, -1,  4, -1,
				 *  3, -1, -1,  7,
				 * -1,  2,  5, -1,
				 *  6,  0, -1, -1
				 *
				 * Naddachance
				 *  1, -1,  4, -1,
				 *  5, -1, -1, -1,
				 * -1,  2, -1, -1,
				 *  3,  0, -1, -1
				 *
				 * TFA
				 *  1, -1, -1, -1,
				 * -1, -1, -1, -1,
				 * -1,  2, -1, -1,
				 * -1, -0, -1, -1
				 */

				/* Unknown table #2
				reader.BaseStream.Seek(keyTwoOffset, SeekOrigin.Begin);
				for (int i = 0; i < numKeyTwo; i += 1)
				{
					// Appears to be between 16-20 shorts?
					System.Console.WriteLine(reader.ReadInt16());
				}
				/* OhGodNo
				 *  2,  7,  1, -1,
				 * -1, 10, 19, -1,
				 *  11, 3, -1, -1,
				 *  8, -1, 14,  5,
				 * 12,  0,  4,  6
				 *
				 * Naddachance
				 *  2,  3, -1, -1,
				 *  9, -1,  7, -1,
				 * 10,  0,  1,  5,
				 * -1, -1, -1, -1
				 *
				 * TFA
				 *  2,  3, -1, -1,
				 * -1, -1, -1, -1,
				 * -1,  0,  1,  5,
				 * -1, -1, -1, -1
				 */

				// Obtain the Audio Category Names
				reader.BaseStream.Seek(categoryNameOffset, SeekOrigin.Begin);
				string[] categoryNames = new string[numCategories];
				for (int i = 0; i < numCategories; i += 1)
				{
					List<char> builtString = new List<char>();
					while (reader.PeekChar() != 0)
					{
						builtString.Add(reader.ReadChar());
					}
					reader.ReadChar(); // Null terminator
					categoryNames[i] = new string(builtString.ToArray());
				}

				// Obtain the Audio Categories
				reader.BaseStream.Seek(categoryOffset, SeekOrigin.Begin);
				INTERNAL_categories = new List<AudioCategory>();
				for (int i = 0; i < numCategories; i += 1)
				{
					// Maximum instances
					byte maxInstances = reader.ReadByte();

					// Fade In/Out
					ushort fadeInMS = reader.ReadUInt16();
					ushort fadeOutMS = reader.ReadUInt16();

					// Instance Behavior Flags
					byte instanceFlags = reader.ReadByte();
					int fadeType = instanceFlags & 0x07;
					int maxBehavior = instanceFlags >> 3;

					// Unknown value
					reader.ReadUInt16();

					// Volume
					float volume = XACTCalculator.CalculateVolume(reader.ReadByte());

					// Visibility Flags, unused
					reader.ReadByte();

					// Add to the engine list
					INTERNAL_categories.Add(
						new AudioCategory(
							categoryNames[i],
							volume,
							maxInstances,
							maxBehavior,
							fadeInMS,
							fadeOutMS,
							fadeType
						)
					);
				}

				// Obtain the Variable Names
				reader.BaseStream.Seek(variableNameOffset, SeekOrigin.Begin);
				string[] variableNames = new string[numVariables];
				for (int i = 0; i < numVariables; i += 1)
				{
					List<char> builtString = new List<char>();
					while (reader.PeekChar() != 0)
					{
						builtString.Add(reader.ReadChar());
					}
					reader.ReadChar(); // Null terminator
					variableNames[i] = new string(builtString.ToArray());
				}

				// Obtain the Variables
				reader.BaseStream.Seek(variableOffset, SeekOrigin.Begin);
				INTERNAL_variables = new List<Variable>();
				for (int i = 0; i < numVariables; i += 1)
				{
					// Variable Accessibility (See Variable constructor)
					byte varFlags = reader.ReadByte();

					// Variable Value, Boundaries
					float initialValue =	reader.ReadSingle();
					float minValue =	reader.ReadSingle();
					float maxValue =	reader.ReadSingle();

					// Add to the engine list
					INTERNAL_variables.Add(
						new Variable(
							variableNames[i],
							(varFlags & 0x01) != 0,
							(varFlags & 0x02) != 0,
							(varFlags & 0x04) == 0,
							(varFlags & 0x08) != 0,
							initialValue,
							minValue,
							maxValue
						)
					);
				}

				// Obtain the RPC Curves
				reader.BaseStream.Seek(rpcOffset, SeekOrigin.Begin);
				INTERNAL_RPCs = new Dictionary<long, RPC>();
				for (int i = 0; i < numRPCs; i += 1)
				{
					// RPC "Code", used by the SoundBanks
					long rpcCode = reader.BaseStream.Position;

					// RPC Variable
					ushort rpcVariable = reader.ReadUInt16();

					// Number of RPC Curve Points
					byte numPoints = reader.ReadByte();

					// RPC Parameter
					ushort rpcParameter = reader.ReadUInt16();

					// RPC Curve Points
					RPCPoint[] rpcPoints = new RPCPoint[numPoints];
					for (byte j = 0; j < numPoints; j += 1)
					{
						float x = reader.ReadSingle();
						float y = reader.ReadSingle();
						byte type = reader.ReadByte();
						rpcPoints[j] = new RPCPoint(
							x, y,
							(RPCPointType) type
						);
					}

					// Add to the engine list
					INTERNAL_RPCs.Add(
						rpcCode,
						new RPC(
							INTERNAL_variables[rpcVariable].Name,
							rpcParameter,
							rpcPoints
						)
					);
				}

				// Obtain the DSP Parameters
				reader.BaseStream.Seek(dspParameterOffset, SeekOrigin.Begin);
				INTERNAL_dspParameters = new List<DSPParameter>();
				for (int i = 0; i < numDSPParameters; i += 1)
				{
					// Effect Parameter Type
					byte type = reader.ReadByte();

					// Effect value, boundaries
					float value = reader.ReadSingle();
					float minVal = reader.ReadSingle();
					float maxVal = reader.ReadSingle();

					// Unknown value
					reader.ReadUInt16();

					// Add to Parameter list
					INTERNAL_dspParameters.Add(
						new DSPParameter(
							type,
							value,
							minVal,
							maxVal
						)
					);
				}

				// Obtain the DSP Presets
				reader.BaseStream.Seek(dspPresetOffset, SeekOrigin.Begin);
				INTERNAL_dspPresets = new Dictionary<long, DSPPreset>();
				int total = 0;
				for (int i = 0; i < numDSPPresets; i += 1)
				{
					// DSP "Code", used by the SoundBanks
					long dspCode = reader.BaseStream.Position;

					// Preset Accessibility
					bool global = (reader.ReadByte() == 1);

					// Number of preset parameters
					uint numParams = reader.ReadUInt32();

					// Obtain DSP Parameters
					DSPParameter[] parameters = new DSPParameter[numParams];
					for (uint j = 0; j < numParams; j += 1)
					{
						parameters[j] = INTERNAL_dspParameters[total];
						total += 1;
					}

					// Add to DSP Preset list
					INTERNAL_dspPresets.Add(
						dspCode,
						new DSPPreset(
							global,
							parameters
						)
					);
				}
			}

			// Create the WaveBank Dictionary
			INTERNAL_waveBanks = new Dictionary<string, WaveBank>();

			// Finally.
			IsDisposed = false;
		}
示例#3
0
        public RPC(
			string rpcVariable,
			ushort rpcParameter,
			RPCPoint[] rpcPoints
		)
        {
            Variable = rpcVariable;
            Parameter = (RPCParameter) rpcParameter;
            Points = rpcPoints;
        }
示例#4
0
        public AudioEngine(string settingsFile)
        {
            if (String.IsNullOrEmpty(settingsFile))
            {
                throw new ArgumentNullException("settingsFile");
            }

            using (Stream stream = TitleContainer.OpenStream(settingsFile))
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    // Check the file header. Should be 'XGFS'
                    if (reader.ReadUInt32() != 0x46534758)
                    {
                        throw new ArgumentException("XGFS format not recognized!");
                    }

                    // Check the Content and Tool versions
                    if (reader.ReadUInt16() != ContentVersion)
                    {
                        throw new ArgumentException("XGFS Content version!");
                    }
                    if (reader.ReadUInt16() != 42)
                    {
                        throw new ArgumentException("XGFS Tool version!");
                    }

                    // Unknown value
                    reader.ReadUInt16();

                    // Last Modified, Unused
                    reader.ReadUInt64();

                    // Unknown value
                    reader.ReadByte();

                    // Number of AudioCategories
                    ushort numCategories = reader.ReadUInt16();

                    // Number of XACT Variables
                    ushort numVariables = reader.ReadUInt16();

                    // Unknown value, KEY#1 Length?
                    reader.ReadUInt16();

                    // Unknown value, KEY#2 Length?
                    reader.ReadUInt16();

                    // Number of RPC Variables
                    ushort numRPCs = reader.ReadUInt16();

                    // Number of DSP Presets/Parameters
                    ushort numDSPPresets    = reader.ReadUInt16();
                    ushort numDSPParameters = reader.ReadUInt16();

                    // Category Offset in XGS File
                    uint categoryOffset = reader.ReadUInt32();

                    // Variable Offset in XGS File
                    uint variableOffset = reader.ReadUInt32();

                    // Unknown value, KEY#1 Offset?
                    reader.ReadUInt32();

                    // Category Name Index Offset, unused
                    reader.ReadUInt32();

                    // Unknown value, KEY#2 Offset?
                    reader.ReadUInt32();

                    // Variable Name Index Offset, unused
                    reader.ReadUInt32();

                    // Category Name Offset in XGS File
                    uint categoryNameOffset = reader.ReadUInt32();

                    // Variable Name Offset in XGS File
                    uint variableNameOffset = reader.ReadUInt32();

                    // RPC Variable Offset in XGS File
                    uint rpcOffset = reader.ReadUInt32();

                    // DSP Preset/Parameter Offsets in XGS File
                    uint dspPresetOffset    = reader.ReadUInt32();
                    uint dspParameterOffset = reader.ReadUInt32();

                    // Obtain the Audio Category Names
                    reader.BaseStream.Seek(categoryNameOffset, SeekOrigin.Begin);
                    string[] categoryNames = new string[numCategories];
                    for (int i = 0; i < numCategories; i += 1)
                    {
                        List <char> builtString = new List <char>();
                        while (reader.PeekChar() != 0)
                        {
                            builtString.Add(reader.ReadChar());
                        }
                        reader.ReadChar();                 // Null terminator
                        categoryNames[i] = new string(builtString.ToArray());
                    }

                    // Obtain the Audio Categories
                    reader.BaseStream.Seek(categoryOffset, SeekOrigin.Begin);
                    INTERNAL_categories = new List <AudioCategory>();
                    for (int i = 0; i < numCategories; i += 1)
                    {
                        // Maximum instances
                        byte maxInstances = reader.ReadByte();

                        // Fade In/Out
                        ushort fadeInMS  = reader.ReadUInt16();
                        ushort fadeOutMS = reader.ReadUInt16();

                        // Instance Behavior Flags
                        int maxBehavior = reader.ReadByte() & 0x0F;                 // FIXME: What?

                        // Unknown value
                        reader.ReadUInt16();

                        // Volume
                        float volume = XACTCalculator.CalculateVolume(reader.ReadByte());

                        // Visibility Flags, unused
                        reader.ReadByte();

                        // Add to the engine list
                        INTERNAL_categories.Add(
                            new AudioCategory(
                                categoryNames[i],
                                volume,
                                maxInstances,
                                maxBehavior,
                                fadeInMS,
                                fadeOutMS
                                )
                            );
                    }

                    // Obtain the Variable Names
                    reader.BaseStream.Seek(variableNameOffset, SeekOrigin.Begin);
                    string[] variableNames = new string[numVariables];
                    for (int i = 0; i < numVariables; i += 1)
                    {
                        List <char> builtString = new List <char>();
                        while (reader.PeekChar() != 0)
                        {
                            builtString.Add(reader.ReadChar());
                        }
                        reader.ReadChar();                 // Null terminator
                        variableNames[i] = new string(builtString.ToArray());
                    }

                    // Obtain the Variables
                    reader.BaseStream.Seek(variableOffset, SeekOrigin.Begin);
                    INTERNAL_variables = new List <Variable>();
                    for (int i = 0; i < numVariables; i += 1)
                    {
                        // Variable Accessibility (See Variable constructor)
                        byte varFlags = reader.ReadByte();

                        // Variable Value, Boundaries
                        float initialValue = reader.ReadSingle();
                        float minValue     = reader.ReadSingle();
                        float maxValue     = reader.ReadSingle();

                        // Add to the engine list
                        INTERNAL_variables.Add(
                            new Variable(
                                variableNames[i],
                                (varFlags & 0x01) != 0,
                                (varFlags & 0x02) != 0,
                                (varFlags & 0x04) == 0,
                                (varFlags & 0x08) != 0,
                                initialValue,
                                minValue,
                                maxValue
                                )
                            );
                    }

                    // Append built-in properties to Variable list
                    bool hasVolume = false;
                    foreach (Variable curVar in INTERNAL_variables)
                    {
                        if (curVar.Name.Equals("Volume"))
                        {
                            hasVolume = true;
                        }
                    }
                    if (!hasVolume)
                    {
                        INTERNAL_variables.Add(
                            new Variable(
                                "Volume",
                                true,
                                false,
                                false,
                                false,
                                1.0f,
                                0.0f,
                                1.0f
                                )
                            );
                    }

                    // Obtain the RPC Curves
                    reader.BaseStream.Seek(rpcOffset, SeekOrigin.Begin);
                    INTERNAL_RPCs = new Dictionary <long, RPC>();
                    for (int i = 0; i < numRPCs; i += 1)
                    {
                        // RPC "Code", used by the SoundBanks
                        long rpcCode = reader.BaseStream.Position;

                        // RPC Variable
                        ushort rpcVariable = reader.ReadUInt16();

                        // Number of RPC Curve Points
                        byte numPoints = reader.ReadByte();

                        // RPC Parameter
                        ushort rpcParameter = reader.ReadUInt16();

                        // RPC Curve Points
                        RPCPoint[] rpcPoints = new RPCPoint[numPoints];
                        for (byte j = 0; j < numPoints; j += 1)
                        {
                            float x    = reader.ReadSingle();
                            float y    = reader.ReadSingle();
                            byte  type = reader.ReadByte();
                            rpcPoints[j] = new RPCPoint(
                                x, y,
                                (RPCPointType)type
                                );
                        }

                        // Add to the engine list
                        INTERNAL_RPCs.Add(
                            rpcCode,
                            new RPC(
                                INTERNAL_variables[rpcVariable].Name,
                                rpcParameter,
                                rpcPoints
                                )
                            );
                    }

                    // Obtain the DSP Parameters
                    reader.BaseStream.Seek(dspParameterOffset, SeekOrigin.Begin);
                    INTERNAL_dspParameters = new List <DSPParameter>();
                    for (int i = 0; i < numDSPParameters; i += 1)
                    {
                        // Effect Parameter Type
                        byte type = reader.ReadByte();

                        // Effect value, boundaries
                        float value  = reader.ReadSingle();
                        float minVal = reader.ReadSingle();
                        float maxVal = reader.ReadSingle();

                        // Unknown value
                        reader.ReadUInt16();

                        // Add to Parameter list
                        INTERNAL_dspParameters.Add(
                            new DSPParameter(
                                type,
                                value,
                                minVal,
                                maxVal
                                )
                            );
                    }

                    // Obtain the DSP Presets
                    reader.BaseStream.Seek(dspPresetOffset, SeekOrigin.Begin);
                    INTERNAL_dspPresets = new Dictionary <long, DSPPreset>();
                    int total = 0;
                    for (int i = 0; i < numDSPPresets; i += 1)
                    {
                        // DSP "Code", used by the SoundBanks
                        long dspCode = reader.BaseStream.Position;

                        // Preset Accessibility
                        bool global = (reader.ReadByte() == 1);

                        // Number of preset parameters
                        uint numParams = reader.ReadUInt32();

                        // Obtain DSP Parameters
                        DSPParameter[] parameters = new DSPParameter[numParams];
                        for (uint j = 0; j < numParams; j += 1)
                        {
                            parameters[j] = INTERNAL_dspParameters[total];
                            total        += 1;
                        }

                        // Add to DSP Preset list
                        // FIXME: Did XNA4 PC ever go past Reverb?
                        INTERNAL_dspPresets.Add(
                            dspCode,
                            new DSPPreset(
                                "Reverb",
                                global,
                                parameters
                                )
                            );
                    }
                }

            // Create the WaveBank Dictionary
            INTERNAL_waveBanks = new Dictionary <string, WaveBank>();

            // Finally.
            IsDisposed = false;
        }
示例#5
0
        public AudioEngine(string settingsFile)
        {
            if (String.IsNullOrEmpty(settingsFile))
            {
                throw new ArgumentNullException("settingsFile");
            }

            using (Stream stream = TitleContainer.OpenStream(settingsFile))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                // Check the file header. Should be 'XGFS'
                if (reader.ReadUInt32() != 0x46534758)
                {
                    throw new ArgumentException("XGFS format not recognized!");
                }

                // Check the Content and Tool versions
                if (reader.ReadUInt16() != ContentVersion)
                {
                    throw new ArgumentException("XGFS Content version!");
                }
                if (reader.ReadUInt16() != 42)
                {
                    throw new ArgumentException("XGFS Tool version!");
                }

                // Unknown value
                reader.ReadUInt16();

                // Last Modified, Unused
                reader.ReadUInt64();

                // Unknown value
                reader.ReadByte();

                // Number of AudioCategories
                ushort numCategories = reader.ReadUInt16();

                // Number of XACT Variables
                ushort numVariables = reader.ReadUInt16();

                // Unknown value, KEY#1 Length?
                reader.ReadUInt16();

                // Unknown value, KEY#2 Length?
                reader.ReadUInt16();

                // Number of RPC Variables
                ushort numRPCs = reader.ReadUInt16();

                // Number of DSP Presets/Parameters
                ushort numDSPPresets = reader.ReadUInt16();
                ushort numDSPParameters = reader.ReadUInt16();

                // Category Offset in XGS File
                uint categoryOffset = reader.ReadUInt32();

                // Variable Offset in XGS File
                uint variableOffset = reader.ReadUInt32();

                // Unknown value, KEY#1 Offset?
                reader.ReadUInt32();

                // Category Name Index Offset, unused
                reader.ReadUInt32();

                // Unknown value, KEY#2 Offset?
                reader.ReadUInt32();

                // Variable Name Index Offset, unused
                reader.ReadUInt32();

                // Category Name Offset in XGS File
                uint categoryNameOffset = reader.ReadUInt32();

                // Variable Name Offset in XGS File
                uint variableNameOffset = reader.ReadUInt32();

                // RPC Variable Offset in XGS File
                uint rpcOffset = reader.ReadUInt32();

                // DSP Preset/Parameter Offsets in XGS File
                uint dspPresetOffset = reader.ReadUInt32();
                uint dspParameterOffset = reader.ReadUInt32();

                // Obtain the Audio Category Names
                reader.BaseStream.Seek(categoryNameOffset, SeekOrigin.Begin);
                string[] categoryNames = new string[numCategories];
                for (int i = 0; i < numCategories; i += 1)
                {
                    List<char> builtString = new List<char>();
                    while (reader.PeekChar() != 0)
                    {
                        builtString.Add(reader.ReadChar());
                    }
                    reader.ReadChar(); // Null terminator
                    categoryNames[i] = new string(builtString.ToArray());
                }

                // Obtain the Audio Categories
                reader.BaseStream.Seek(categoryOffset, SeekOrigin.Begin);
                INTERNAL_categories = new List<AudioCategory>();
                for (int i = 0; i < numCategories; i += 1)
                {
                    // Maximum instances
                    byte maxInstances = reader.ReadByte();

                    // Fade In/Out
                    ushort fadeInMS = reader.ReadUInt16();
                    ushort fadeOutMS = reader.ReadUInt16();

                    // Instance Behavior Flags
                    int maxBehavior = reader.ReadByte() & 0x0F; // FIXME: What?

                    // Unknown value
                    reader.ReadUInt16();

                    // Volume
                    float volume = XACTCalculator.CalculateVolume(reader.ReadByte());

                    // Visibility Flags, unused
                    reader.ReadByte();

                    // Add to the engine list
                    INTERNAL_categories.Add(
                        new AudioCategory(
                            categoryNames[i],
                            volume,
                            maxInstances,
                            maxBehavior,
                            fadeInMS,
                            fadeOutMS
                        )
                    );
                }

                // Obtain the Variable Names
                reader.BaseStream.Seek(variableNameOffset, SeekOrigin.Begin);
                string[] variableNames = new string[numVariables];
                for (int i = 0; i < numVariables; i += 1)
                {
                    List<char> builtString = new List<char>();
                    while (reader.PeekChar() != 0)
                    {
                        builtString.Add(reader.ReadChar());
                    }
                    reader.ReadChar(); // Null terminator
                    variableNames[i] = new string(builtString.ToArray());
                }

                // Obtain the Variables
                reader.BaseStream.Seek(variableOffset, SeekOrigin.Begin);
                INTERNAL_variables = new List<Variable>();
                for (int i = 0; i < numVariables; i += 1)
                {
                    // Variable Accessibility (See Variable constructor)
                    byte varFlags = reader.ReadByte();

                    // Variable Value, Boundaries
                    float initialValue =	reader.ReadSingle();
                    float minValue =	reader.ReadSingle();
                    float maxValue =	reader.ReadSingle();

                    // Add to the engine list
                    INTERNAL_variables.Add(
                        new Variable(
                            variableNames[i],
                            (varFlags & 0x01) != 0,
                            (varFlags & 0x02) != 0,
                            (varFlags & 0x04) == 0,
                            (varFlags & 0x08) != 0,
                            initialValue,
                            minValue,
                            maxValue
                        )
                    );
                }

                // Append built-in properties to Variable list
                bool hasVolume = false;
                foreach (Variable curVar in INTERNAL_variables)
                {
                    if (curVar.Name.Equals("Volume"))
                    {
                        hasVolume = true;
                    }
                }
                if (!hasVolume)
                {
                    INTERNAL_variables.Add(
                        new Variable(
                            "Volume",
                            true,
                            false,
                            false,
                            false,
                            1.0f,
                            0.0f,
                            1.0f
                        )
                    );
                }

                // Obtain the RPC Curves
                reader.BaseStream.Seek(rpcOffset, SeekOrigin.Begin);
                INTERNAL_RPCs = new Dictionary<long, RPC>();
                for (int i = 0; i < numRPCs; i += 1)
                {
                    // RPC "Code", used by the SoundBanks
                    long rpcCode = reader.BaseStream.Position;

                    // RPC Variable
                    ushort rpcVariable = reader.ReadUInt16();

                    // Number of RPC Curve Points
                    byte numPoints = reader.ReadByte();

                    // RPC Parameter
                    ushort rpcParameter = reader.ReadUInt16();

                    // RPC Curve Points
                    RPCPoint[] rpcPoints = new RPCPoint[numPoints];
                    for (byte j = 0; j < numPoints; j += 1)
                    {
                        float x = reader.ReadSingle();
                        float y = reader.ReadSingle();
                        byte type = reader.ReadByte();
                        rpcPoints[j] = new RPCPoint(
                            x, y,
                            (RPCPointType) type
                        );
                    }

                    // Add to the engine list
                    INTERNAL_RPCs.Add(
                        rpcCode,
                        new RPC(
                            INTERNAL_variables[rpcVariable].Name,
                            rpcParameter,
                            rpcPoints
                        )
                    );
                }

                // Obtain the DSP Parameters
                reader.BaseStream.Seek(dspParameterOffset, SeekOrigin.Begin);
                INTERNAL_dspParameters = new List<DSPParameter>();
                for (int i = 0; i < numDSPParameters; i += 1)
                {
                    // Effect Parameter Type
                    byte type = reader.ReadByte();

                    // Effect value, boundaries
                    float value = reader.ReadSingle();
                    float minVal = reader.ReadSingle();
                    float maxVal = reader.ReadSingle();

                    // Unknown value
                    reader.ReadUInt16();

                    // Add to Parameter list
                    INTERNAL_dspParameters.Add(
                        new DSPParameter(
                            type,
                            value,
                            minVal,
                            maxVal
                        )
                    );
                }

                // Obtain the DSP Presets
                reader.BaseStream.Seek(dspPresetOffset, SeekOrigin.Begin);
                INTERNAL_dspPresets = new Dictionary<long, DSPPreset>();
                int total = 0;
                for (int i = 0; i < numDSPPresets; i += 1)
                {
                    // DSP "Code", used by the SoundBanks
                    long dspCode = reader.BaseStream.Position;

                    // Preset Accessibility
                    bool global = (reader.ReadByte() == 1);

                    // Number of preset parameters
                    uint numParams = reader.ReadUInt32();

                    // Obtain DSP Parameters
                    DSPParameter[] parameters = new DSPParameter[numParams];
                    for (uint j = 0; j < numParams; j += 1)
                    {
                        parameters[j] = INTERNAL_dspParameters[total];
                        total += 1;
                    }

                    // Add to DSP Preset list
                    INTERNAL_dspPresets.Add(
                        dspCode,
                        new DSPPreset(
                            global,
                            parameters
                        )
                    );
                }
            }

            // Create the WaveBank Dictionary
            INTERNAL_waveBanks = new Dictionary<string, WaveBank>();

            // Finally.
            IsDisposed = false;
        }