Esempio n. 1
0
        public static void Main(string[] args)
        {
            var pinCS0 = GpioPin.FromNumber(25); // Pin 22 (BCM 25)
            var pinCS1 = GpioPin.FromNumber(26); // Pin 37 (BCM 26)
            var pinRST = GpioPin.FromNumber(16); // Pin 36 (BCM 16)

            var spiSettings = new SpiConnectionSettings(busId: 0, chipSelectLine: 0);
            var gpioPinMap  = new Dictionary <TargetChip, ChipPinConfig>
            {
                [TargetChip.Board0] = new ChipPinConfig(csPin: pinCS0, resetPin: pinRST),
                [TargetChip.Board1] = new ChipPinConfig(csPin: pinCS1, resetPin: pinRST),
            };

            using (var spiDevice = new UnixSpiDevice(spiSettings))
                using (var gpioController = new GpioController(PinNumberingScheme.Logical))
                    using (var ymf825Device = new NativeSpi(spiDevice, gpioController, gpioPinMap))
                    {
                        var driver = new Ymf825Driver(ymf825Device);
                        driver.EnableSectionMode();

                        Console.WriteLine("Software Reset");
                        driver.ResetSoftware();

                        SetupTones(driver);

                        var index = 0;
                        var score = new[]
                        {
                            60, 62, 64, 65, 67, 69, 71, 72,
                            72, 74, 76, 77, 79, 81, 83, 84,
                            84, 83, 81, 79, 77, 76, 74, 72,
                            72, 71, 69, 67, 65, 64, 62, 60
                        };

                        while (true)
                        {
                            const int noteOnTime = 250;
                            const int sleepTime  = 0;

                            NoteOn(driver, score[index]);
                            Thread.Sleep(noteOnTime);
                            NoteOff(driver);

                            Thread.Sleep(sleepTime);

                            if (Console.KeyAvailable)
                            {
                                break;
                            }

                            index++;
                            if (index >= score.Length)
                            {
                                index = 0;
                            }
                        }

                        driver.ResetHardware();
                    }
        }
Esempio n. 2
0
        public MidiDriver(IList <ToneItem> toneItems, IList <EqualizerItem> equalizerItems, Ymf825Driver driver)
        {
            ToneItems      = toneItems;
            EqualizerItems = equalizerItems;
            Driver         = driver;
            Driver.EnableSectionMode();

            for (var i = 0; i < 16; i++)
            {
                noteOnKeys[i]  = -1;
                pitchBends[i]  = 1.0;
                corrections[i] = 1.0;

                volumes[i]     = 100.0 / 127.0;
                toneVolumes[i] = 1.0;
                lchVolumes[i]  = 1.0;
                rchVolumes[i]  = 1.0;
                expressions[i] = 1.0;

                rpnMsb[i]         = 127;
                rpnLsb[i]         = 127;
                fineTune[i]       = 1.0;
                pitchBendWidth[i] = 2.0;
            }
        }
Esempio n. 3
0
        private void ConnectDevice()
        {
            DeviceInfo = Spi.GetDeviceInfoList()[toolStripComboBox_deviceList.SelectedIndex];
            ymf825     = new CbwYmf825Bb(toolStripComboBox_deviceList.SelectedIndex);
            Driver     = new Ymf825Driver(ymf825);

            ymf825.DataWrote += (sender, args) =>
            {
                registerMap.SetData(args.Address, args.Data);
            };
            ymf825.DataBurstWrote += (sender, args) =>
            {
                if (args.Data.Count <= 0)
                {
                    return;
                }

                if (args.Address == 0x07)
                {
                    registerMap.SetData(args.Address, args.Data.Last());

                    var toneNumber = args.Data[0] - 0x80;

                    if (toneNumber < 0 || toneNumber > 16 || args.Data.Count < toneNumber * 30 + 5)
                    {
                        Console.WriteLine($"Invalid BurstWrite Data - Tone Number: {toneNumber}, Data Size: {args.Data.Count} (required {toneNumber * 30 + 5})");
                        return;
                    }

                    for (var i = 0; i < toneNumber; i++)
                    {
                        for (var j = 0; j < 30; j++)
                        {
                            toneParameterRegisterMap[i].SetData(j, args.Data[i * 30 + j + 1]);
                        }
                    }
                }
                else if (args.Address >= 0x20 || args.Address <= 0x22)
                {
                    var eq = args.Address - 0x20;

                    if (args.Data.Count < 5)
                    {
                        return;
                    }

                    for (var i = 0; i < 5; i++)
                    {
                        registerMap.SetData(0x23 + 3 * eq + i, args.Data[i]);
                    }
                }
            };

            SpiConnected = true;
            Driver.ResetHardware();
            Driver.ResetSoftware();
            Connected?.Invoke(this, new EventArgs());
        }
Esempio n. 4
0
 private void DisconnectDevice()
 {
     Driver?.ResetHardware();
     Driver = null;
     ymf825?.Dispose();
     ymf825       = null;
     SpiConnected = false;
     Disconnected?.Invoke(this, new EventArgs());
 }
Esempio n. 5
0
        private void PitchBend(int channel, int data1, int data2)
        {
            var bendData = ((data2 << 7) | data1) - 8192;

            pitchBends[channel] = Math.Pow(Math.Pow(2.0, pitchBendWidth[channel] / 12.0), bendData / 8192.0);
            var correction = corrections[channel] * pitchBends[channel] * fineTune[channel];

            Ymf825Driver.ConvertForFrequencyMultiplier(correction, out var integer, out var fraction);

            Driver.Section(() =>
            {
                Driver.SetVoiceNumber(channel);
                Driver.SetFrequencyMultiplier(integer, fraction);
            });
        }
Esempio n. 6
0
        private static void NoteOn(Ymf825Driver driver, int key)
        {
            Ymf825Driver.GetFnumAndBlock(key, out var fnum, out var block, out var correction);
            Ymf825Driver.ConvertForFrequencyMultiplier(correction, out var integer, out var fraction);
            var freq = Ymf825Driver.CalcFrequency(fnum, block);

            Console.WriteLine($"key: {key}, freq: {freq:f1} Hz, fnum: {fnum:f0}, block: {block}, correction: {correction:f3}, integer: {integer}, fraction: {fraction}");

            driver.Section(() =>
            {
                driver.SetVoiceNumber(0);
                driver.SetVoiceVolume(15);
                driver.SetFrequencyMultiplier(integer, fraction);
                driver.SetFnumAndBlock((int)Math.Round(fnum), block);
                driver.SetToneFlag(0, true, false, false);
            });
        }
Esempio n. 7
0
        private void SendNoteOn(int channel, int key, int velocity)
        {
            var volume = velocity / 127.0;

            Ymf825Driver.GetFnumAndBlock(key, out var fnum, out var block, out var correction);
            corrections[channel] = correction;
            correction          *= pitchBends[channel] * fineTune[channel];
            Ymf825Driver.ConvertForFrequencyMultiplier(correction, out var integer, out var fraction);

            Driver.Section(() =>
            {
                Driver.SetVoiceNumber(channel);
                Driver.SetChannelVolume((int)Math.Round(volume * 31.0), false);
                Driver.SetFrequencyMultiplier(integer, fraction);
                Driver.SetFnumAndBlock((int)Math.Round(fnum), block);
                Driver.SetToneFlag(channel, true, false, false);
            });
        }
Esempio n. 8
0
        private void Rpn(int channel)
        {
            if (rpnMsb[channel] == 0 && rpnLsb[channel] == 1)
            {
                var bendData = ((dataEntryMsb[channel] << 7) | dataEntryLsb[channel]) - 8192;
                // precalc: Math.Pow(2.0, 2.0 / 12.0) = 1.122462048309373
                fineTune[channel] = Math.Pow(Math.Pow(2.0, 2.0 / 12.0), bendData / 8192.0);
                var correction = corrections[channel] * pitchBends[channel] * fineTune[channel];

                Ymf825Driver.ConvertForFrequencyMultiplier(correction, out var integer, out var fraction);

                Driver.Section(() =>
                {
                    Driver.SetVoiceNumber(channel);
                    Driver.SetFrequencyMultiplier(integer, fraction);
                });
            }
            if (rpnMsb[channel] == 0 && rpnLsb[channel] == 0)
            {
                pitchBendWidth[channel] = dataEntryMsb[channel];
            }
        }
Esempio n. 9
0
        private static void SetupTones(Ymf825Driver driver)
        {
            Console.WriteLine("Tone Init");
            var tones = new ToneParameterCollection {
                [0] = ToneParameter.GetSine()
            };

            driver.Section(() =>
            {
                driver.WriteContentsData(tones, 0);
                driver.SetSequencerSetting(SequencerSetting.AllKeyOff | SequencerSetting.AllMute | SequencerSetting.AllEgReset |
                                           SequencerSetting.R_FIFOR | SequencerSetting.R_SEQ | SequencerSetting.R_FIFO);
            }, 1);

            driver.Section(() =>
            {
                driver.SetSequencerSetting(SequencerSetting.Reset);

                driver.SetToneFlag(0, false, true, true);
                driver.SetChannelVolume(31, true);
                driver.SetVibratoModuration(0);
                driver.SetFrequencyMultiplier(1, 0);
            });
        }
Esempio n. 10
0
 private static void NoteOff(Ymf825Driver driver)
 => driver.Section(() => driver.SetToneFlag(0, false, false, false));
Esempio n. 11
0
        private static void Main()
        {
            Console.WriteLine("Image type: {0}bit", Environment.Is64BitProcess ? "64" : "32");

            if (D2XxSpi.DeviceCount < 1)
            {
                return;
            }

            using (var ymf825 = SelectInterface())
            {
                var driver = new Ymf825Driver(ymf825);
                driver.EnableSectionMode();

                Console.WriteLine("Software Reset");
                driver.ResetSoftware();

                {
                    Console.WriteLine("Tone Init");
                    var tones = new ToneParameterCollection {
                        [0] = ToneParameter.GetSine()
                    };

                    driver.Section(() =>
                    {
                        driver.WriteContentsData(tones, 0);
                        driver.SetSequencerSetting(SequencerSetting.AllKeyOff | SequencerSetting.AllMute | SequencerSetting.AllEgReset |
                                                   SequencerSetting.R_FIFOR | SequencerSetting.R_SEQ | SequencerSetting.R_FIFO);
                    }, 1);

                    driver.Section(() =>
                    {
                        driver.SetSequencerSetting(SequencerSetting.Reset);

                        driver.SetToneFlag(0, false, true, true);
                        driver.SetChannelVolume(31, true);
                        driver.SetVibratoModuration(0);
                        driver.SetFrequencyMultiplier(1, 0);
                    });
                }

                var noteon = new Action <int>(key =>
                {
                    Ymf825Driver.GetFnumAndBlock(key, out var fnum, out var block, out var correction);
                    Ymf825Driver.ConvertForFrequencyMultiplier(correction, out var integer, out var fraction);
                    var freq = Ymf825Driver.CalcFrequency(fnum, block);
                    Console.WriteLine("key: {0}, freq: {4:f1} Hz, fnum: {5:f0}, block: {6}, correction: {1:f3}, integer: {2}, fraction: {3}", key, correction, integer, fraction, freq, fnum, block);

                    driver.Section(() =>
                    {
                        driver.SetVoiceNumber(0);
                        driver.SetVoiceVolume(15);
                        driver.SetFrequencyMultiplier(integer, fraction);
                        driver.SetFnumAndBlock((int)Math.Round(fnum), block);
                        driver.SetToneFlag(0, true, false, false);
                    });
                });

                var noteoff = new Action(() =>
                {
                    driver.Section(() => driver.SetToneFlag(0, false, false, false));
                });

                var index = 0;
                var score = new[]
                {
                    60, 62, 64, 65, 67, 69, 71, 72,
                    72, 74, 76, 77, 79, 81, 83, 84,
                    84, 83, 81, 79, 77, 76, 74, 72,
                    72, 71, 69, 67, 65, 64, 62, 60
                };
                while (true)
                {
                    const int noteOnTime = 250;
                    const int sleepTime  = 0;

                    noteon(score[index]);
                    Thread.Sleep(noteOnTime);
                    noteoff();

                    Thread.Sleep(sleepTime);

                    if (Console.KeyAvailable)
                    {
                        break;
                    }

                    index++;
                    if (index >= score.Length)
                    {
                        index = 0;
                    }
                }

                ymf825.InvokeHardwareReset();
            }
        }
Esempio n. 12
0
        private static void Run(Options options)
        {
            const int    resolution       = 1000;
            const double tickSeconds      = 1.0 / resolution;
            const double tickMilliSeconds = tickSeconds * 1000;

            var savePath = GetSavePath(options);

            if (File.Exists(savePath))
            {
                File.Delete(savePath);
            }

            using (var zipArchive = ZipFile.Open(savePath, ZipArchiveMode.Create))
            {
                using (var fileStream = zipArchive.CreateEntry("config.json", CompressionLevel.Optimal).Open())
                    using (var sw = new StreamWriter(fileStream))
                    {
                        var config = new Dictionary <string, object>
                        {
                            { "version", 0 },
                            { "resolution", resolution }
                        };
                        sw.Write(JsonConvert.SerializeObject(config));
                    }

                using (var fileStream = zipArchive.CreateEntry("dump", CompressionLevel.Optimal).Open())
                    using (var dumpWriter = new DumpWriter(fileStream))
                    {
                        var sequence       = new Sequence(options.InputFile);
                        var sequencer      = new Sequencer(sequence);
                        var ymf825DumpChip = new Ymf825DumpChip(dumpWriter);
                        var ymf825Driver   = new Ymf825Driver(ymf825DumpChip);
                        var project        = LoadProject(options);
                        var driver         = new MidiDriver(project.Tones.ToArray(), project.Equalizers.ToArray(), ymf825Driver);
                        var stopped        = false;

                        ymf825Driver.EnableSectionMode();
                        ymf825Driver.SleepAction += i =>
                        {
                            var tick = (int)Math.Ceiling(i / tickMilliSeconds);

                            if (dumpWriter.Disposed)
                            {
                                return;
                            }

                            dumpWriter.RealtimeWait((ushort)tick);
                        };
                        driver.Start();

                        sequencer.OnTrackEvent += (sender, args) =>
                        {
                            foreach (var argsEvent in args.Events)
                            {
                                driver.ProcessMidiEvent(argsEvent);
                            }
                        };
                        sequencer.SequenceEnd += (sender, args) => stopped = true;
                        sequencer.Tick         = 0L;

                        while (!stopped)
                        {
                            sequencer.Progress(tickSeconds);
                            dumpWriter.Wait(1);
                        }
                    }
            }
        }