/// <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(); }
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); } }
/// <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; }