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