示例#1
0
        public MainPage()
        {
            this.InitializeComponent();
            App.Current.Suspending += Current_Suspending;
            mArduino        = new ArduinoManager();
            mGPIO           = new GPIOManager();
            mGameNoteIndexs = new int[5] {
                0, 0, 0, 0, 0
            };
            mCurrentGameNote = new MidiGameNote[5];
            mIsInited        = false;
            mIsPlaying       = false;


            Task.Run(async() =>
            {
                SMFReader r = new SMFReader();
                mSMF        = await r.Read(@"Assets\out.mid");
                var w       = new MidiDeviceWatcher(MidiOutPort.GetDeviceSelector(), Dispatcher);
                w.Start();
                var col  = w.GetDeviceInformationCollection();
                var l    = await DeviceInformation.FindAllAsync(MidiOutPort.GetDeviceSelector());
                MIDIPort = await MidiOutPort.FromIdAsync(l[0].Id);
                await mArduino.Init();
                await mGPIO.Init(GpioController.GetDefault());
                mGPIO.MidiButtonChanged += MGPIO_MidiButtonChanged;
                mGPIO.JoyButtonChanged  += MGPIO_JoyButtonChanged;
                mPlayer                   = new SMFPlayer(mSMF, MIDIPort);
                mPlayer.OnLED            += Player_OnLED;
                mPlayer.OnBarBeatChanged += Player_BarBeatChanged;
                mPlayer.OnTempoChanged   += Player_OnTempoChanged;
                mGPIO.Ack();
                mIsInited = true;
            });
            mVolTimer          = new DispatcherTimer();
            mVolTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);
            mVolTimer.Tick    += MVolTimer_Tick;
            mVolTimer.Start();
        }
示例#2
0
 public SMFPlayer(SMF smf, IMidiOutPort p)
 {
     mSMF  = smf;
     mMidi = p;
 }
示例#3
0
        public async Task <SMF> Read(String path)
        {
            SMF   smf    = new SMF();
            ulong cursol = 0;
            var   sf     = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(path);

            using (Stream fs = await sf.OpenStreamForReadAsync())
            {
                SMFByte = new byte[fs.Length];
                fs.Read(SMFByte, 0, SMFByte.Length);
            }

            byte[] head     = ReadAsBytes(cursol, 4); cursol += 4;
            ulong  head_len = ReadAsInt64(cursol); cursol += 4;

            smf.FormatType = ReadAsInt(cursol);   cursol += 2;
            smf.TrackNum   = ReadAsInt(cursol);     cursol += 2;
            smf.TimeMode   = ReadAsInt(cursol); cursol += 2;

            for (int i = 0; i < smf.TrackNum; i++)
            {
                byte[] track     = ReadAsBytes(cursol, 4); cursol += 4;
                ulong  track_len = ReadAsInt64(cursol); cursol += 4;
                ulong  time      = 0;
                for (ulong c = cursol; c < track_len + cursol;)
                {
                    var dt = ReadVlen(c);    c += dt.Item2;
                    time += dt.Item1;
                    //小節へ変換
                    byte dat = SMFByte[c];
                    if ((dat & 0xF0) == 0xF0)
                    {
                        byte   type  = SMFByte[c + 1]; c += 2;
                        var    len   = ReadVlen(c); c += len.Item2;
                        byte[] exdat = ReadAsBytes(c, len.Item1); c += len.Item1;
                        ulong  beat  = time / smf.TimeMode;
                        uint   tick  = (uint)(time % smf.TimeMode);
                        switch (type)
                        {
                        case 0x51:
                            smf.SystemEvents.Add(new TempoEvent(beat, tick, exdat[0], exdat[1], exdat[2]));
                            break;

                        case 0x58:
                            smf.SystemEvents.Add(new MeterEvent(beat, tick, exdat[0], exdat[1], exdat[2], exdat[3]));
                            break;

                        case 0x59:
                            smf.SystemEvents.Add(new KeyEvent(beat, tick, exdat[0], exdat[1]));
                            break;
                        }

                        /*
                         *
                         * FF type len dats
                         * FF 01-05 len text
                         * FF 2F 00     End of Track
                         * FF 51 03 tempo(3byte)    Set Tempo   テンポ。 4分音符の長さをマイクロ秒単位で表現。
                         * FF 58 04 nn dd cc bb     Time Signature  拍子nn=分子 dd=分子(2の負のべき乗で表す) cc=メトロノーム間隔(四分音符間隔なら18H) bb=四分音符あたりの三十二分音符の数
                         * FFH 59H 02H sf ml    Key Signature   キー(調)を表す sf=正・・シャープの数 負・・フラットの数 ml=0・・・長調 1・・・短調
                         */
                    }
                    else
                    {
                        byte ch = (byte)(dat & 0x0F);
                        switch (dat & 0xF0)
                        {
                        case 0x80:
                            if (ch == 0 && SMFByte[c + 2] <= 5 && smf.GameNotes[SMFByte[c + 2]].Count > 0)
                            {
                                foreach (var mg in smf.GameNotes[SMFByte[c + 2]])
                                {
                                    if (mg.Note == SMFByte[c + 1] && !mg.IsSetEnd)
                                    {
                                        mg.IsSetEnd = true;
                                        mg.EndTick  = time;
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                smf.CHData[ch].Add(new NoteOFF(ch, time, SMFByte[c + 1], SMFByte[c + 2]));
                            }
                            c += 3;
                            break;

                        case 0x90:
                            if (ch == 0 && SMFByte[c + 2] <= 5)
                            {
                                smf.GameNotes[SMFByte[c + 2]].Add(
                                    new MidiGameNote(time, SMFByte[c + 1]));
                            }
                            else
                            {
                                smf.CHData[ch].Add(new NoteON(ch, time, SMFByte[c + 1], SMFByte[c + 2]));
                            }
                            c += 3;
                            break;

                        case 0xB0:
                            if (SMFByte[c + 1] == 12)
                            {
                                smf.SystemEvents.Add(new LEDEvent(time / smf.TimeMode, (uint)(time % smf.TimeMode), SMFByte[c + 2]));
                            }
                            else
                            {
                                smf.CHData[ch].Add(new ControleChange(ch, time, SMFByte[c + 1], SMFByte[c + 2]));
                            }
                            c += 3;
                            break;

                        case 0xC0:
                            smf.CHData[ch].Add(new ProgramChange(ch, time, SMFByte[c + 1]));
                            c += 2;
                            break;

                        case 0xE0:
                            smf.CHData[ch].Add(new PitchBend(ch, time, SMFByte[c + 1], SMFByte[c + 2]));
                            c += 3;
                            break;
                        }
                    }
                }
                cursol += track_len;
            }
            smf.InitMidiMessage();
            return(smf);
        }