Ejemplo n.º 1
0
        public static void InitAndReset(int apuIdx, int sampleRate, int expansion, [MarshalAs(UnmanagedType.FunctionPtr)] DmcReadDelegate dmcCallback)
        {
            Init(apuIdx, sampleRate, expansion, dmcCallback);
            Reset(apuIdx);
            WriteRegister(apuIdx, APU_SND_CHN, 0x0f);    // enable channels, stop DMC
            WriteRegister(apuIdx, APU_TRI_LINEAR, 0x80); // disable triangle length counter
            WriteRegister(apuIdx, APU_NOISE_HI, 0x00);   // load noise length
            WriteRegister(apuIdx, APU_PL1_VOL, 0x30);    // volumes to 0
            WriteRegister(apuIdx, APU_PL2_VOL, 0x30);
            WriteRegister(apuIdx, APU_NOISE_VOL, 0x30);
            WriteRegister(apuIdx, APU_PL1_SWEEP, 0x08);  // no sweep
            WriteRegister(apuIdx, APU_PL2_SWEEP, 0x08);

            // These were the default values in Nes_Snd_Emu, review eventually.
            // FamiTracker by default has -24, 12000 respectively.
            const double treble = -8.87;
            const int    cutoff = 8800;

            TrebleEq(apuIdx, NesApu.APU_EXPANSION_NONE, treble, cutoff, sampleRate);

            switch (expansion)
            {
            case APU_EXPANSION_VRC6:
                WriteRegister(apuIdx, VRC6_CTRL, 0x00);      // No halt, no octave change
                TrebleEq(apuIdx, expansion, treble, cutoff, sampleRate);
                break;

            case APU_EXPANSION_FDS:
                // These are taken from FamiTracker. They smooth out the waveform extremely nicely!
                TrebleEq(apuIdx, expansion, -48, 1000, sampleRate);
                break;

            case APU_EXPANSION_MMC5:
                WriteRegister(apuIdx, MMC5_SND_CHN, 0x03);     // Enable both square channels.
                break;

            case APU_EXPANSION_VRC7:
                WriteRegister(apuIdx, VRC7_SILENCE, 0x00);     // Enable VRC7 audio.
                break;
            }
        }
Ejemplo n.º 2
0
        public static void InitAndReset(int apuIdx, int sampleRate, bool pal, int expansion, int numExpansionChannels, [MarshalAs(UnmanagedType.FunctionPtr)] DmcReadDelegate dmcCallback)
        {
            Init(apuIdx, sampleRate, pal ? 1 : 0, expansion, dmcCallback);
            Reset(apuIdx);
            WriteRegister(apuIdx, APU_SND_CHN, 0x0f);    // enable channels, stop DMC
            WriteRegister(apuIdx, APU_TRI_LINEAR, 0x80); // disable triangle length counter
            WriteRegister(apuIdx, APU_NOISE_HI, 0x00);   // load noise length
            WriteRegister(apuIdx, APU_PL1_VOL, 0x30);    // volumes to 0
            WriteRegister(apuIdx, APU_PL2_VOL, 0x30);
            WriteRegister(apuIdx, APU_NOISE_VOL, 0x30);
            WriteRegister(apuIdx, APU_PL1_SWEEP, 0x08);  // no sweep
            WriteRegister(apuIdx, APU_PL2_SWEEP, 0x08);

            // These were the default values in Nes_Snd_Emu, review eventually.
            // FamiTracker by default has -24, 12000 respectively.
            const double treble = -8.87;
            const int    cutoff = 8800;

            TrebleEq(apuIdx, NesApu.APU_EXPANSION_NONE, treble, cutoff, sampleRate);

            switch (expansion)
            {
            case APU_EXPANSION_VRC6:
                WriteRegister(apuIdx, VRC6_CTRL, 0x00);      // No halt, no octave change
                TrebleEq(apuIdx, expansion, treble, cutoff, sampleRate);
                break;

            case APU_EXPANSION_FDS:
                // These are taken from FamiTracker. They smooth out the waveform extremely nicely!
                //TrebleEq(apuIdx, expansion, -48, 1000, sampleRate);
                TrebleEq(apuIdx, expansion, -15, 2000, sampleRate);
                break;

            case APU_EXPANSION_MMC5:
                WriteRegister(apuIdx, MMC5_PL1_VOL, 0x10);
                WriteRegister(apuIdx, MMC5_PL2_VOL, 0x10);
                WriteRegister(apuIdx, MMC5_SND_CHN, 0x03);     // Enable both square channels.
                break;

            case APU_EXPANSION_VRC7:
                WriteRegister(apuIdx, VRC7_SILENCE, 0x00);     // Enable VRC7 audio.
                break;

            case APU_EXPANSION_NAMCO:
                // This is mainly because the instrument player might not update all the channels all the time.
                WriteRegister(apuIdx, N163_ADDR, N163_REG_VOLUME);
                WriteRegister(apuIdx, N163_DATA, (numExpansionChannels - 1) << 4);
                TrebleEq(apuIdx, expansion, -15, 4000, sampleRate);
                break;

            case APU_EXPANSION_SUNSOFT:
                WriteRegister(apuIdx, S5B_ADDR, S5B_REG_TONE);
                WriteRegister(apuIdx, S5B_DATA, 0x38);     // No noise, just 3 tones for now.
                break;
            }
        }
Ejemplo n.º 3
0
 public extern static int Init(int apuIdx, int sampleRate, int pal, int expansion, [MarshalAs(UnmanagedType.FunctionPtr)] DmcReadDelegate dmcCallback);
Ejemplo n.º 4
0
        public static void InitAndReset(int apuIdx, int sampleRate, bool pal, int seperateTndMode, int expansions, int numNamcoChannels, [MarshalAs(UnmanagedType.FunctionPtr)] DmcReadDelegate dmcCallback)
        {
            Init(apuIdx, sampleRate, pal ? 1 : 0, seperateTndMode, expansions, dmcCallback);
            Reset(apuIdx);
            WriteRegister(apuIdx, APU_SND_CHN, 0x0f);    // enable channels, stop DMC
            WriteRegister(apuIdx, APU_TRI_LINEAR, 0x80); // disable triangle length counter
            WriteRegister(apuIdx, APU_NOISE_HI, 0x00);   // load noise length
            WriteRegister(apuIdx, APU_PL1_VOL, 0x30);    // volumes to 0
            WriteRegister(apuIdx, APU_PL2_VOL, 0x30);
            WriteRegister(apuIdx, APU_NOISE_VOL, 0x30);
            WriteRegister(apuIdx, APU_PL1_SWEEP, 0x08);  // no sweep
            WriteRegister(apuIdx, APU_PL2_SWEEP, 0x08);

            var apuSettings = Settings.ExpansionMixerSettings[NesApu.APU_EXPANSION_NONE];

            TrebleEq(apuIdx, NesApu.APU_EXPANSION_NONE, apuSettings.treble, sampleRate);
            SetExpansionVolume(apuIdx, NesApu.APU_EXPANSION_NONE, Utils.DbToAmplitude(apuSettings.volume + Settings.GlobalVolume));

            if (expansions != APU_EXPANSION_MASK_NONE)
            {
                for (int expansion = APU_EXPANSION_FIRST; expansion <= APU_EXPANSION_LAST; expansion++)
                {
                    if ((expansions & ExpansionToMask(expansion)) != 0)
                    {
                        var expSettings = Settings.ExpansionMixerSettings[expansion];

                        TrebleEq(apuIdx, expansion, expSettings.treble, sampleRate);
                        SetExpansionVolume(apuIdx, expansion, Utils.DbToAmplitude(expSettings.volume + Settings.GlobalVolume));

                        switch (expansion)
                        {
                        case APU_EXPANSION_VRC6:
                            WriteRegister(apuIdx, VRC6_CTRL, 0x00);      // No halt, no octave change
                            break;

                        case APU_EXPANSION_FDS:
                            break;

                        case APU_EXPANSION_MMC5:
                            WriteRegister(apuIdx, MMC5_PL1_VOL, 0x10);
                            WriteRegister(apuIdx, MMC5_PL2_VOL, 0x10);
                            WriteRegister(apuIdx, MMC5_SND_CHN, 0x03);     // Enable both square channels.
                            break;

                        case APU_EXPANSION_VRC7:
                            // HACK : There is a conflict between the VRC7 silence register and S5B data register, a write to
                            // the silence register (E000) will be interpreted as a S5B data write. To prevent this, we
                            // select a dummy register for S5B so that the write is discarded.
                            if ((expansions & APU_EXPANSION_MASK_SUNSOFT) != 0)
                            {
                                WriteRegister(apuIdx, S5B_ADDR, S5B_REG_IO_A);
                            }
                            WriteRegister(apuIdx, VRC7_SILENCE, 0x00);     // Enable VRC7 audio.
                            break;

                        case APU_EXPANSION_NAMCO:
                            // This is mainly because the instrument player might not update all the channels all the time.
                            WriteRegister(apuIdx, N163_ADDR, N163_REG_VOLUME);
                            WriteRegister(apuIdx, N163_DATA, (numNamcoChannels - 1) << 4);
                            break;

                        case APU_EXPANSION_SUNSOFT:
                            WriteRegister(apuIdx, S5B_ADDR, S5B_REG_TONE);
                            WriteRegister(apuIdx, S5B_DATA, 0x38);     // No noise, just 3 tones for now.
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public static void InitAndReset(int apuIdx, int sampleRate, bool pal, int expansion, int numExpansionChannels, [MarshalAs(UnmanagedType.FunctionPtr)] DmcReadDelegate dmcCallback)
        {
            Init(apuIdx, sampleRate, pal ? 1 : 0, expansion, dmcCallback);
            Reset(apuIdx);
            WriteRegister(apuIdx, APU_SND_CHN, 0x0f);    // enable channels, stop DMC
            WriteRegister(apuIdx, APU_TRI_LINEAR, 0x80); // disable triangle length counter
            WriteRegister(apuIdx, APU_NOISE_HI, 0x00);   // load noise length
            WriteRegister(apuIdx, APU_PL1_VOL, 0x30);    // volumes to 0
            WriteRegister(apuIdx, APU_PL2_VOL, 0x30);
            WriteRegister(apuIdx, APU_NOISE_VOL, 0x30);
            WriteRegister(apuIdx, APU_PL1_SWEEP, 0x08);  // no sweep
            WriteRegister(apuIdx, APU_PL2_SWEEP, 0x08);

            var apuSettings = Settings.ExpansionMixerSettings[NesApu.APU_EXPANSION_NONE];
            var expSettings = Settings.ExpansionMixerSettings[expansion];

            TrebleEq(apuIdx, NesApu.APU_EXPANSION_NONE, apuSettings.treble, sampleRate);
            SetExpansionVolume(apuIdx, NesApu.APU_EXPANSION_NONE, Utils.DbToAmplitude(apuSettings.volume));

            if (expansion != APU_EXPANSION_NONE)
            {
                TrebleEq(apuIdx, expansion, expSettings.treble, sampleRate);
                SetExpansionVolume(apuIdx, expansion, Utils.DbToAmplitude(expSettings.volume));
            }

            switch (expansion)
            {
            case APU_EXPANSION_VRC6:
                WriteRegister(apuIdx, VRC6_CTRL, 0x00);      // No halt, no octave change
                break;

            case APU_EXPANSION_FDS:
                break;

            case APU_EXPANSION_MMC5:
                WriteRegister(apuIdx, MMC5_PL1_VOL, 0x10);
                WriteRegister(apuIdx, MMC5_PL2_VOL, 0x10);
                WriteRegister(apuIdx, MMC5_SND_CHN, 0x03);     // Enable both square channels.
                break;

            case APU_EXPANSION_VRC7:
                WriteRegister(apuIdx, VRC7_SILENCE, 0x00);     // Enable VRC7 audio.
                break;

            case APU_EXPANSION_NAMCO:
                // This is mainly because the instrument player might not update all the channels all the time.
                WriteRegister(apuIdx, N163_ADDR, N163_REG_VOLUME);
                WriteRegister(apuIdx, N163_DATA, (numExpansionChannels - 1) << 4);
                break;

            case APU_EXPANSION_SUNSOFT:
                WriteRegister(apuIdx, S5B_ADDR, S5B_REG_TONE);
                WriteRegister(apuIdx, S5B_DATA, 0x38);     // No noise, just 3 tones for now.
                break;
            }
        }