예제 #1
0
        private void Ym2612WriteData(byte address, int op, int slot, byte data)
        {
            switch (op)
            {
            case 0:
                op = 0;
                break;

            case 1:
                op = 2;
                break;

            case 2:
                op = 1;
                break;

            case 3:
                op = 3;
                break;
            }

            uint yreg = (uint)(0 / 3) * 2;

            comPortOPNA2?.DeferredWriteData(0, (byte)((1 + (yreg + 0)) * 4), (byte)(address + (op * 4) + (slot % 3)), (int)Settings.Default.BitBangWaitOPNA2);
            comPortOPNA2?.DeferredWriteData(0, (byte)((1 + (yreg + 1)) * 4), data, (int)Settings.Default.BitBangWaitOPNA2);
        }
예제 #2
0
        protected override void StopAllSounds(bool volumeOff)
        {
            if (comPortDCSG != null)
            {
                comPortDCSG.ClearDeferredWriteData();

                switch (comPortDCSG?.SoundModuleType)
                {
                case VsifSoundModuleType.Genesis:
                case VsifSoundModuleType.Genesis_Low:
                case VsifSoundModuleType.Genesis_FTDI:
                    for (int i = 0; i < 3; i++)
                    {
                        comPortDCSG.WriteData(0, 0x14, (byte)(0x80 | i << 5 | 0x1f), (int)Settings.Default.BitBangWaitDCSG);
                    }
                    comPortDCSG.WriteData(0, 0x14, (byte)(0x80 | 3 << 5 | 0x1f), (int)Settings.Default.BitBangWaitDCSG);
                    break;

                case VsifSoundModuleType.SMS:
                    for (int i = 0; i < 3; i++)
                    {
                        comPortDCSG.WriteData(0, 0xFF, (byte)(0x80 | i << 5 | 0x1f), (int)Settings.Default.BitBangWaitOPNA2);
                    }
                    comPortDCSG.WriteData(0, 0xFF, (byte)(0x80 | 3 << 5 | 0x1f), (int)Settings.Default.BitBangWaitOPNA2);
                    break;
                }
                comPortDCSG.FlushDeferredWriteData();
            }
            if (comPortOPNA2 != null)
            {
                comPortOPNA2.ClearDeferredWriteData();

                for (int i = 0; i < 3; i++)
                {
                    comPortOPNA2.DeferredWriteData(0, 4, (byte)(0xB4 | i), (int)Settings.Default.BitBangWaitOPNA2);
                    comPortOPNA2.DeferredWriteData(0, 8, 0xC0, (int)Settings.Default.BitBangWaitOPNA2);
                    comPortOPNA2.DeferredWriteData(0, 12, (byte)(0xB4 | i), (int)Settings.Default.BitBangWaitOPNA2);
                    comPortOPNA2.DeferredWriteData(0, 16, 0xC0, (int)Settings.Default.BitBangWaitOPNA2);
                }

                // disable LFO
                comPortOPNA2.DeferredWriteData(0, 4, 0x22, (int)Settings.Default.BitBangWaitOPNA2);
                comPortOPNA2.DeferredWriteData(0, 8, 0x00, (int)Settings.Default.BitBangWaitOPNA2);

                // disable timer & set channel 6 to normal mode
                comPortOPNA2.DeferredWriteData(0, 4, 0x27, (int)Settings.Default.BitBangWaitOPNA2);
                comPortOPNA2.DeferredWriteData(0, 8, 0x00, (int)Settings.Default.BitBangWaitOPNA2);

                // ALL KEY OFF
                comPortOPNA2.DeferredWriteData(0, 4, 0x28, (int)Settings.Default.BitBangWaitOPNA2);
                for (int i = 0; i < 3; i++)
                {
                    comPortOPNA2.DeferredWriteData(0, 8, (byte)(0x00 | i), (int)Settings.Default.BitBangWaitOPNA2);
                    comPortOPNA2.DeferredWriteData(0, 8, (byte)(0x04 | i), (int)Settings.Default.BitBangWaitOPNA2);
                }

                // disable DAC
                comPortOPNA2.DeferredWriteData(0, 4, 0x2B, (int)Settings.Default.BitBangWaitOPNA2);
                comPortOPNA2.DeferredWriteData(0, 8, 0x00, (int)Settings.Default.BitBangWaitOPNA2);

                for (int slot = 0; slot < 6; slot++)
                {
                    uint reg = (uint)(slot / 3) * 2;
                    Ym2612WriteData(0x28, 0, 0, (byte)(0x00 | (reg << 1) | (byte)(slot % 3)));

                    //TL
                    if (volumeOff)
                    {
                        for (int op = 0; op < 4; op++)
                        {
                            Ym2612WriteData(0x40, op, slot, 127);
                        }
                    }
                }

                //if (volumeOff)
                //    for (int slot = 0; slot < 6; slot++)
                //        for (int op = 0; op < 4; op++)
                //            Ym2612WriteData(0x80, op, slot, 0x0ff);

                comPortOPNA2.FlushDeferredWriteData();
            }

            Thread.Sleep(50);
        }
예제 #3
0
        protected override void StreamSong()
        {
            xgmReader.BaseStream?.Seek(0, SeekOrigin.Begin);
            double wait            = 0;
            double xgmWaitDelta    = 0;
            double streamWaitDelta = 0;
            double lastDiff        = 0;

            using (SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero, false, null))
            {
                long freq, before, after;
                QueryPerformanceFrequency(out freq);

                SampleData[] currentPlaySamples = new SampleData[4];

                while (true)
                {
                    QueryPerformanceCounter(out before);

                    if (State == SoundState.Stopped)
                    {
                        break;
                    }
                    else if (State == SoundState.Paused)
                    {
                        Thread.Sleep(1);
                        continue;
                    }
                    try
                    {
                        if (xgmWaitDelta <= 0)
                        {
                            int command = readByte();
                            if (command != -1)
                            {
                                switch (command)
                                {
                                case int cmd when 0x0 <= cmd && cmd <= 0x0F:
                                {
                                    switch (xgmMHead.bytNTSC_PAL & 1)
                                    {
                                    case 0:
                                        xgmWaitDelta += 735;
                                        break;

                                    case 1:
                                        xgmWaitDelta += 882;
                                        break;
                                    }
                                    flushDeferredWriteData();
                                    break;
                                }

                                case int cmd when 0x10 <= cmd && cmd <= 0x1F:
                                {
                                    int size = cmd & 0xf;
                                    for (int i = 0; i <= size; i++)
                                    {
                                        var data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        switch (comPortDCSG?.SoundModuleType)
                                        {
                                        case VsifSoundModuleType.Genesis:
                                        case VsifSoundModuleType.Genesis_Low:
                                        case VsifSoundModuleType.Genesis_FTDI:
                                            comPortDCSG?.DeferredWriteData(0, 0x14, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                            break;

                                        case VsifSoundModuleType.SMS:
                                            comPortDCSG?.DeferredWriteData(0, 0xFF, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                            break;
                                        }
                                    }
                                }
                                break;

                                case int cmd when 0x20 <= cmd && cmd <= 0x2F:     //YM2612 Write Port 0
                                {
                                    int size = cmd & 0xf;
                                    for (int i = 0; i <= size; i++)
                                    {
                                        var data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        comPortOPNA2?.DeferredWriteData(0, 0x04, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                        data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        comPortOPNA2?.DeferredWriteData(0, 0x08, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                    }
                                }
                                break;

                                case int cmd when 0x30 <= cmd && cmd <= 0x3F:     //YM2612 Write Port 1
                                {
                                    int size = cmd & 0xf;
                                    for (int i = 0; i <= size; i++)
                                    {
                                        var data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        comPortOPNA2?.DeferredWriteData(0, 0x0C, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                        data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        comPortOPNA2?.DeferredWriteData(0, 0x10, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                    }
                                }
                                break;

                                case int cmd when 0x40 <= cmd && cmd <= 0x4F:     //YM2612 Write Port 0
                                {
                                    int size = cmd & 0xf;
                                    for (int i = 0; i <= size; i++)
                                    {
                                        var data = readByte();
                                        if (data < 0)
                                        {
                                            break;
                                        }
                                        comPortOPNA2?.DeferredWriteData(0, 0x04, 0x28, (int)Settings.Default.BitBangWaitOPNA2);
                                        comPortOPNA2?.DeferredWriteData(0, 0x08, (byte)data, (int)Settings.Default.BitBangWaitOPNA2);
                                    }
                                }
                                break;

                                case int cmd when 0x50 <= cmd && cmd <= 0x5F:     //Play PCM
                                {
                                    int ch = cmd & 0x3;

                                    var id = readByte();
                                    if (id < 0)
                                    {
                                        break;
                                    }
                                    if (id == 0)
                                    {
                                        currentPlaySamples[ch] = null;
                                    }
                                    else
                                    {
                                        currentPlaySamples[ch] = SampleDataTable[id - 1];
                                        currentPlaySamples[ch].Restart();
                                    }
                                }
                                break;

                                case 0x7E:
                                    flushDeferredWriteData();
                                    uint ofst = xgmReader.ReadUInt32();
                                    if (ofst < 0)
                                    {
                                        xgmReader.BaseStream?.Seek(0, SeekOrigin.Begin);
                                    }
                                    else
                                    {
                                        xgmReader.BaseStream?.Seek((int)ofst, SeekOrigin.Begin);
                                    }
                                    break;

                                case 0x7F:
                                    flushDeferredWriteData();
                                    //End of song
                                    xgmReader.BaseStream?.Seek(0, SeekOrigin.Begin);
                                    break;
                                }
                            }
                            if ((command == 0x7E || command == 0x7F || command == -1))
                            {
                                flushDeferredWriteData();
                                if (Looped == false || LoopCount == 0)
                                {
                                    State = SoundState.Stopped;
                                    NotifyFinished();
                                    break;
                                }
                                LoopCount--;
                            }
                        }

                        if (streamWaitDelta <= 0)
                        {
                            short dacData = 0;
                            bool  playDac = false;
                            for (int i = 0; i < currentPlaySamples.Length; i++)
                            {
                                var dt = currentPlaySamples[i]?.GetDacData();
                                if (dt != null)
                                {
                                    dacData += (short)dt.Value;
                                    playDac  = true;
                                }
                            }

                            if (playDac)
                            {
                                if (dacData > sbyte.MaxValue)
                                {
                                    dacData = sbyte.MaxValue;
                                }
                                else if (dacData < sbyte.MinValue)
                                {
                                    dacData = sbyte.MinValue;
                                }
                                dacData += 0x80;

                                comPortOPNA2?.DeferredWriteData(0, 0x04, (byte)0x2a, (int)Settings.Default.BitBangWaitOPNA2);
                                comPortOPNA2?.DeferredWriteData(0, 0x08, (byte)dacData, (int)Settings.Default.BitBangWaitOPNA2);

                                streamWaitDelta += 44.1d / 14d;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.GetType() == typeof(Exception))
                        {
                            throw;
                        }
                        else if (ex.GetType() == typeof(SystemException))
                        {
                            throw;
                        }

                        flushDeferredWriteData();
                        if (Looped == false || LoopCount == 0)
                        {
                            State = SoundState.Stopped;
                            NotifyFinished();
                            break;
                        }
                        LoopCount--;
                        xgmReader.BaseStream?.Seek(0, SeekOrigin.Begin);
                    }

                    if (streamWaitDelta < xgmWaitDelta)
                    {
                        if (streamWaitDelta <= 0)
                        {
                            wait        += xgmWaitDelta;
                            xgmWaitDelta = 0;
                        }
                        else
                        {
                            wait           += streamWaitDelta;
                            xgmWaitDelta   -= streamWaitDelta;
                            streamWaitDelta = 0;
                        }
                    }
                    else
                    {
                        if (xgmWaitDelta <= 0)
                        {
                            wait           += streamWaitDelta;
                            streamWaitDelta = 0;
                        }
                        else
                        {
                            wait            += xgmWaitDelta;
                            streamWaitDelta -= xgmWaitDelta;
                            xgmWaitDelta     = 0;
                        }
                    }

                    if (wait <= (double)Settings.Default.VGMWait)
                    {
                        continue;
                    }

                    flushDeferredWriteData();

                    QueryPerformanceCounter(out after);
                    double pwait = (wait / PlaybackSpeed);
                    if (((double)(after - before) / freq) > (pwait / (44.1 * 1000)))
                    {
                        lastDiff = ((double)(after - before) / freq) - (pwait / (44.1 * 1000));
                        wait     = -(lastDiff * 44.1 * 1000);
                        NotifyProcessLoadOccurred();
                    }
                    else
                    {
                        while (((double)(after - before) / freq) <= (pwait / (44.1 * 1000)))
                        {
                            QueryPerformanceCounter(out after);
                        }
                        wait     = 0;
                        HighLoad = false;
                    }
                }
            }
        }