Exemple #1
0
 public static IALReverb GenReverb(DSPParameter[] parameters)
 {
     if (ALDevice == null)
     {
         throw new NoAudioHardwareException();
     }
     return ALDevice.GenReverb(parameters);
 }
Exemple #2
0
        public DSPReverbEffect(DSPParameter[] parameters)
            : base()
        {
            // Set up the Reverb Effect
            EFX.alEffecti(
                effectHandle,
                EFX.AL_EFFECT_TYPE,
                EFX.AL_EFFECT_EAXREVERB
            );

            // TODO: Use DSP Parameters on EAXReverb Effect. They don't bind very cleanly. :/

            // Bind the Effect to the EffectSlot. XACT will use the EffectSlot.
            EFX.alAuxiliaryEffectSloti(
                Handle,
                EFX.AL_EFFECTSLOT_EFFECT,
                (int) effectHandle
            );
        }
Exemple #3
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;
		}
Exemple #4
0
        public IALReverb GenReverb(DSPParameter[] parameters)
        {
            uint slot, effect;
            EFX.alGenAuxiliaryEffectSlots((IntPtr) 1, out slot);
            EFX.alGenEffects((IntPtr) 1, out effect);
            // Set up the Reverb Effect
            EFX.alEffecti(
                effect,
                EFX.AL_EFFECT_TYPE,
                EFX.AL_EFFECT_EAXREVERB
            );

            IALReverb result = new OpenALReverb(slot, effect);

            // Apply initial values
            SetReverbReflectionsDelay(result, parameters[0].Value);
            SetReverbDelay(result, parameters[1].Value);
            SetReverbPositionLeft(result, parameters[2].Value);
            SetReverbPositionRight(result, parameters[3].Value);
            SetReverbPositionLeftMatrix(result, parameters[4].Value);
            SetReverbPositionRightMatrix(result, parameters[5].Value);
            SetReverbEarlyDiffusion(result, parameters[6].Value);
            SetReverbLateDiffusion(result, parameters[7].Value);
            SetReverbLowEQGain(result, parameters[8].Value);
            SetReverbLowEQCutoff(result, parameters[9].Value);
            SetReverbHighEQGain(result, parameters[10].Value);
            SetReverbHighEQCutoff(result, parameters[11].Value);
            SetReverbRearDelay(result, parameters[12].Value);
            SetReverbRoomFilterFrequency(result, parameters[13].Value);
            SetReverbRoomFilterMain(result, parameters[14].Value);
            SetReverbRoomFilterHighFrequency(result, parameters[15].Value);
            SetReverbReflectionsGain(result, parameters[16].Value);
            SetReverbGain(result, parameters[17].Value);
            SetReverbDecayTime(result, parameters[18].Value);
            SetReverbDensity(result, parameters[19].Value);
            SetReverbRoomSize(result, parameters[20].Value);
            SetReverbWetDryMix(result, parameters[21].Value);

            // Bind the Effect to the EffectSlot. XACT will use the EffectSlot.
            EFX.alAuxiliaryEffectSloti(
                slot,
                EFX.AL_EFFECTSLOT_EFFECT,
                (int) effect
            );

            #if VERBOSE_AL_DEBUGGING
            CheckALError();
            #endif
            return result;
        }
Exemple #5
0
        public DSPPreset(
			bool global,
			DSPParameter[] parameters
		)
        {
            IsGlobal = global;
            Parameters = parameters;

            // FIXME: Did XACT ever go past Reverb? -flibit
            Effect = new DSPReverbEffect(Parameters);
        }
Exemple #6
0
		public IALReverb GenReverb(DSPParameter[] parameters)
		{
			return new NullReverb();
		}
Exemple #7
0
        public DSPPreset(
			bool global,
			DSPParameter[] parameters
		)
        {
            IsGlobal = global;
            Parameters = parameters;

            // FIXME: Did XACT ever go past Reverb? -flibit
            Effect = AudioDevice.GenReverb(Parameters);
        }
Exemple #8
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;
        }