Exemple #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();
        }
Exemple #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);
            }
        }
Exemple #3
0
        /// <summary>
        /// Create MusicXML.scorepartwisePart object by VsqTrack instance.
        /// </summary>
        /// <param name="track"></param>
        /// <param name="timesig_table"></param>
        /// <returns></returns>
        private scorepartwisePart createScorePart(VsqTrack track, TimesigVector timesig_table, TempoVector tempo_table)
        {
            var     part      = new scorepartwisePart();
            var     note_list = quantizeTrack(track, timesig_table, tempo_table);
            var     measures  = new List <scorepartwisePartMeasure>();
            int     measure   = 0;
            Timesig timesig   = new Timesig(0, 0);

            while (0 < note_list.Count)
            {
                int measure_start_clock = timesig_table.getClockFromBarCount(measure);
                int measure_end_clock   = timesig_table.getClockFromBarCount(measure + 1);

                var tempo_change_in_measure = new TempoVector();
                tempo_change_in_measure.AddRange(
                    tempo_table
                    .Where((tempo) => measure_start_clock <= tempo.Clock && tempo.Clock < measure_end_clock)
                    .Select((tempo) => (TempoTableEntry)tempo.Clone()));

                // get the list of TiedEvent, contained in target measure.
                var in_measure_tied_note_list =
                    note_list
                    .Where((tied_event) => {
                    int tied_event_start = tied_event.Clock;
                    int tied_event_end   = tied_event.Clock + tied_event.Length;
                    return
                    ((measure_start_clock <= tied_event_start && tied_event_start < measure_end_clock) ||
                     (measure_start_clock <= tied_event_end && tied_event_end < measure_end_clock) ||
                     (tied_event_start <= measure_start_clock && measure_end_clock <= tied_event_end));
                });

                // get the list of MusicXML.note.
                var in_measure_note_list =
                    in_measure_tied_note_list
                    .SelectMany((tied_event) => {
                    var result = new List <object>();
                    int clock  = tied_event.Clock;
                    foreach (var note in tied_event)
                    {
                        int length = (int)note.duration.First;
                        if (measure_start_clock <= clock && clock + length <= measure_end_clock)
                        {
                            var tempo_change =
                                tempo_change_in_measure
                                .FirstOrDefault((tempo) => tempo.Clock == clock);
                            if (tempo_change != null)
                            {
                                var direction                = new direction();
                                direction.placement          = abovebelow.above;
                                direction.placementSpecified = true;
                                direction.directiontype      = new directiontype[] { new directiontype() };
                                direction.directiontype[0].metronome.Add(new metronome());
                                var perminute   = new perminute();
                                perminute.Value = getTempo(tempo_change).ToString();
                                direction.directiontype[0].metronome[0].Items = new object[] { notetypevalue.quarter, perminute };
                                direction.sound                = new sound();
                                direction.sound.tempo          = getTempo(tempo_change);
                                direction.sound.tempoSpecified = true;
                                result.Add(direction);
                            }
                            result.Add(note);
                        }
                        clock += length;
                    }
                    return(result);
                });

                var partwise_measure = new scorepartwisePartMeasure();
                partwise_measure.number = (measure + 1).ToString();
                var items = new List <object>();

                var measure_timesig = timesig_table.getTimesigAt(measure_start_clock);
                if (!measure_timesig.Equals(timesig))
                {
                    var attributes = new MusicXML.attributes();
                    attributes.divisions          = 480;
                    attributes.divisionsSpecified = true;
                    attributes.time = new time[] { new time() };
                    attributes.time[0].beats.Add(measure_timesig.numerator.ToString());
                    attributes.time[0].beattype.Add(measure_timesig.denominator.ToString());
                    attributes.time[0].symbol          = timesymbol.common;
                    attributes.time[0].symbolSpecified = true;
                    items.Add(attributes);
                }
                timesig = measure_timesig;

                items.AddRange(in_measure_note_list);
                partwise_measure.Items = items.ToArray();
                measures.Add(partwise_measure);

                note_list.RemoveAll((tied_event) => tied_event.Clock + tied_event.Length <= measure_end_clock);

                measure++;
            }

            part.measure = measures.ToArray();
            return(part);
        }
Exemple #4
0
 public bool Equals(Timesig rhs)
 {
     return(numerator == rhs.numerator &&
            denominator == rhs.denominator);
 }
        /// <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;
        }