예제 #1
0
 internal void INTERNAL_applyFilter(
     DSPFilter filter,
     float hfGain,
     float lfGain
     )
 {
     if (FilterType == -1)
     {
         return;
     }
     else if (FilterType == 0)
     {
         filter.ApplyLowPassFilter(INTERNAL_alSource, hfGain);
     }
     else if (FilterType == 1)
     {
         filter.ApplyHighPassFilter(INTERNAL_alSource, lfGain);
     }
     else if (FilterType == 2)
     {
         filter.ApplyBandPassFilter(INTERNAL_alSource, hfGain, lfGain);
     }
     if (INTERNAL_alSource != 0)
     {
         AL10.alSourcei(
             INTERNAL_alSource,
             EFX.AL_DIRECT_FILTER,
             (int)filter.Handle
             );
     }
 }
예제 #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
                        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>();

            // Create the device filter
            Filter = new DSPFilter();

            // Finally.
            IsDisposed = false;
        }