Example #1
0
        /// <summary>
        /// vsqファイルのstart_clockクロックからメトロノームを起動する。startは、start_clockをいつから起動したかを指定する。
        /// </summary>
        /// <param name="vsq"></param>
        /// <param name="start_clock"></param>
        /// <param name="start"></param>
        public static void Start(VsqFileEx vsq, int start_clock, double start_time)
        {
            s_queue.clear();
            m_stop_required           = false;
            m_stop_metronome_required = false;
            if (s_device0 == null)
            {
                s_device0 = new MidiDeviceImp(s_metronome_device);
            }
            if (s_metronome_device != s_general_device)
            {
                if (s_device1 == null)
                {
                    s_device1 = new MidiDeviceImp(s_general_device);
                }
            }

            m_vsq         = (VsqFileEx)vsq.clone();
            m_started_sec = m_vsq.getSecFromClock(start_clock);
            ByRef <Integer> bar             = new ByRef <Integer>();
            Timesig         timesig         = m_vsq.getTimesigAt(start_clock, bar);
            int             clock_at_bartop = m_vsq.getClockFromBarCount(bar.value);
            int             clock_step      = 480 * 4 / timesig.denominator;
            int             next_clock      = clock_at_bartop + ((start_clock - clock_at_bartop) / clock_step + 1) * clock_step;

            m_started       = start_time;
            m_started_clock = start_clock;
            m_temp_exit     = false;

            for (int track = 1; track < m_vsq.Track.size(); track++)
            {
#if DEBUG
                AppManager.debugWriteLine("Metronome.Start; track=" + track);
#endif
                for (Iterator <VsqEvent> itr = m_vsq.Track.get(track).getNoteEventIterator(); itr.hasNext();)
                {
                    VsqEvent item = itr.next();
                    if (start_clock <= item.Clock)
                    {
                        MidiQueue q = new MidiQueue();
                        q.Track    = track;
                        q.Channel  = (byte)(track - 1);
                        q.Clock    = item.Clock;
                        q.Note     = (byte)(item.ID.Note);
                        q.Program  = 0;
                        q.Velocity = 0x40;
                        q.Done    += new MidiQueueDoneEventHandler(ReGenerateMidiQueue);
                        s_queue.add(q);
                        break;
                    }
                }
            }

            Collections.sort(s_queue);

            m_thread = new Thread(new ThreadStart(ThreadProc));
            m_thread.IsBackground = true;
            m_thread.Priority     = ThreadPriority.Highest;
            m_thread.Start();
        }
Example #2
0
        public static void RestartMetronome()
        {
            m_stop_metronome_required = false;
            if (m_vsq != null)
            {
                double now     = PortUtil.getCurrentTime();
                double elapsed = ((now - m_started) + 0.25) * m_speed;
                int    clock   = (int)m_vsq.getClockFromSec(m_started_sec + elapsed);

                ByRef <Integer> bar             = new ByRef <Integer>();
                Timesig         timesig         = m_vsq.getTimesigAt(clock, bar);
                int             clock_at_bartop = m_vsq.getClockFromBarCount(bar.value);
                int             clock_step      = 480 * 4 / timesig.denominator;
                int             next_clock      = clock_at_bartop + ((clock - clock_at_bartop) / clock_step + 1) * clock_step;

                MidiQueue mq = new MidiQueue();
                mq.Track    = 0;
                mq.Clock    = next_clock;
                mq.Channel  = 14;
                mq.Program  = ProgramNormal;
                mq.Note     = NoteNormal;
                mq.Velocity = 0x40;
                mq.Done    += new MidiQueueDoneEventHandler(ReGenerateMidiQueue);
                s_queue.add(mq);

                if ((next_clock - clock_at_bartop) % (timesig.numerator * clock_step) == 0)
                {
                    MidiQueue mq_bell = new MidiQueue();
                    mq_bell.Track    = 0;
                    mq_bell.Clock    = next_clock;
                    mq_bell.Channel  = 15;
                    mq_bell.Program  = ProgramBell;
                    mq_bell.Note     = NoteBell;
                    mq_bell.Velocity = 0x40;
                    s_queue.add(mq_bell);
                }
                Collections.sort(s_queue);
            }
        }
Example #3
0
        /// <summary>
        /// vsqファイルのstart_clockクロックからメトロノームを起動する。startは、start_clockをいつから起動したかを指定する。
        /// </summary>
        /// <param name="vsq"></param>
        /// <param name="start_clock"></param>
        /// <param name="start"></param>
        public static void Start( VsqFileEx vsq, int start_clock, double start_time ) {
            s_queue.clear();
            m_stop_required = false;
            m_stop_metronome_required = false;
            if ( s_device0 == null ) {
                s_device0 = new MidiDeviceImp( s_metronome_device );
            }
            if ( s_metronome_device != s_general_device ) {
                if ( s_device1 == null ) {
                    s_device1 = new MidiDeviceImp( s_general_device );
                }
            }

            m_vsq = (VsqFileEx)vsq.clone();
            m_started_sec = m_vsq.getSecFromClock( start_clock );
            ByRef<Integer> bar = new ByRef<Integer>();
            Timesig timesig = m_vsq.getTimesigAt( start_clock, bar );
            int clock_at_bartop = m_vsq.getClockFromBarCount( bar.value );
            int clock_step = 480 * 4 / timesig.denominator;
            int next_clock = clock_at_bartop + ((start_clock - clock_at_bartop) / clock_step + 1) * clock_step;
            m_started = start_time;
            m_started_clock = start_clock;
            m_temp_exit = false;

            for ( int track = 1; track < m_vsq.Track.size(); track++ ) {
#if DEBUG
                AppManager.debugWriteLine( "Metronome.Start; track=" + track );
#endif
                for ( Iterator<VsqEvent> itr = m_vsq.Track.get( track ).getNoteEventIterator(); itr.hasNext(); ) {
                    VsqEvent item = itr.next();
                    if ( start_clock <= item.Clock ) {
                        MidiQueue q = new MidiQueue();
                        q.Track = track;
                        q.Channel = (byte)(track - 1);
                        q.Clock = item.Clock;
                        q.Note = (byte)(item.ID.Note);
                        q.Program = 0;
                        q.Velocity = 0x40;
                        q.Done += new MidiQueueDoneEventHandler( ReGenerateMidiQueue );
                        s_queue.add( q );
                        break;
                    }
                }
            }

            Collections.sort( s_queue );

            m_thread = new Thread( new ThreadStart( ThreadProc ) );
            m_thread.IsBackground = true;
            m_thread.Priority = ThreadPriority.Highest;
            m_thread.Start();
        }
        /// <summary>
        /// numStartBar, numStartBeat, numEndBar, numEndBeatの値の範囲の妥当性をチェックする
        /// </summary>
        private void validateNumRange()
        {
            int       startBar  = getStartBar();
            int       startBeat = getStartBeat();
            int       endBar    = getEndBar();
            int       endBeat   = getEndBeat();
            VsqFileEx vsq       = AppManager.getVsqFile();

            if (vsq == null)
            {
                return;
            }

            int preMeasure = vsq.getPreMeasure();

            startBar += (preMeasure - 1); // 曲頭からの小節数は、表示上の小節数と(preMeasure - 1)だけずれているので。
            endBar   += (preMeasure - 1);
            startBeat--;
            endBeat--;

            int     startBarClock = vsq.getClockFromBarCount(startBar);                             // startBar小節開始位置のゲートタイム
            Timesig startTimesig  = vsq.getTimesigAt(startBarClock);                                // startBar小節開始位置の拍子
            int     startClock    = startBarClock + startBeat * 480 * 4 / startTimesig.denominator; // 第startBar小節の第startBeat拍開始位置のゲートタイム

            int     endBarClock = vsq.getClockFromBarCount(endBar);
            Timesig endTimesig  = vsq.getTimesigAt(endBarClock);
            int     endClock    = endBarClock + endBeat * 480 * 4 / endTimesig.denominator;

            if (endClock <= startClock)
            {
                // 選択範囲が0以下の場合、値を強制的に変更する
                // ここでは、一拍分を選択するように変更
                endClock = startClock + 480 * 4 / startTimesig.denominator;
                endBar   = vsq.getBarCountFromClock(endClock);
                int remain = endClock - vsq.getClockFromBarCount(endBar);
                endTimesig = vsq.getTimesigAt(endClock);
                endBeat    = remain / (480 * 4 / endTimesig.denominator);
            }

            // numStartBarの最大値・最小値を決定
            int startBarMax = endBar - 1;

            if (startBeat < endBeat)
            {
                startBarMax = endBar;
            }
            int startBarMin = 1;

            // numStartBeatの最大値・最小値を決定
            int startBeatMax = startTimesig.numerator;

            if (startBar == endBar)
            {
                startBeatMax = endBeat - 1;
            }
            int startBeatMin = 1;

            // numEndBarの最大値・最小値を決定
            int endBarMax = int.MaxValue;
            int endBarMin = startBar + 1;

            if (startBeat < endBeat)
            {
                endBarMin = startBar;
            }

            // numEndBeatの最大値・最小値の決定
            int endBeatMax = endTimesig.numerator;
            int endBeatMin = 1;

            if (startBar == endBar)
            {
                endBeatMin = startBeat + 1;
            }

            lockRequired         = true;
            numStartBar.Maximum  = startBarMax;
            numStartBar.Minimum  = startBarMin;
            numStartBeat.Maximum = startBeatMax;
            numStartBeat.Minimum = startBeatMin;
            numEndBar.Maximum    = endBarMax;
            numEndBar.Minimum    = endBarMin;
            numEndBeat.Maximum   = endBeatMax;
            numEndBeat.Minimum   = endBeatMin;
            lockRequired         = false;
        }