private static void appendParameterEvents(EventQueueSequence list, VsqBPList cle, int parameter_index, int clock_start, int clock_end) { int max = cle.getMaximum(); int min = cle.getMinimum(); float order = 1.0f / (float)(max - min); if (cle != null) { int keycount = cle.size(); for (int i = 0; i < keycount; i++) { int clock = cle.getKeyClock(i); if (clock_start <= clock && clock <= clock_end) { int value = cle.getElementA(i); MidiEventQueue queue = list.get(clock); ParameterEvent pe = new ParameterEvent(); pe.index = parameter_index; pe.value = (value - min) * order; queue.param.add(pe); } else if (clock_end < clock) { break; } } } }
/// <summary> /// 音符の note on/off のためのイベントを作成し、イベントキューに追加する /// </summary> /// <param name="track">生成元のトラック</param> /// <param name="result">生成したイベントの追加先</param> private void appendNoteEvent(VsqTrack track, EventQueueSequence result) { foreach (var item in track.MetaText.Events.Events) { if (item.ID.type != VsqIDType.Anote) { continue; } var note = item.ID.Note; { var clock = item.Clock; var queue = result.get(clock); var noteOn = driver_.createNoteOnEvent(item.ID.Note, item.ID.Dynamics, item.ID.LyricHandle.L0.Phrase); queue.noteon.AddRange(noteOn); } { var clock = item.Clock + item.ID.Length; var queue = result.get(clock); var noteOff = createNoteOffEvent(clock, item.ID.Note); queue.noteoff.add(noteOff); } } }
/// <summary> /// ピッチとピッチベンドセンシティビティをイベントキューに追加する /// </summary> /// <param name="track"></param> /// <param name="sequence"></param> private void appendPitchEvent(VsqTrack track, EventQueueSequence sequence) { // 実際に AquesTone2 に送信する pbs の値と、pbs カーブに入っている値とのマップ const int maxPitchBendSensitivity = 23; int[] map = new int[maxPitchBendSensitivity + 1] { 0, 5, 15, 35, 44, 54, 64, 74, 84, 93, 103, 113, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, }; var pbs = track.MetaText.PBS; for (int i = 0; i < pbs.size(); ++i) { var clock = pbs.getKeyClock(i); { // RPN MSB = 0x00 var e = new MidiEvent(); e.firstByte = 0xB0; e.data = new int[] { 0x65, 0x00 }; e.clock = clock; sequence.get(clock).pit.add(e); } { // RPN LSB = 0x00 var e = new MidiEvent(); e.firstByte = 0xB0; e.data = new int[] { 0x64, 0x00 }; e.clock = clock; sequence.get(clock).pit.add(e); } { // RPN data MSB var e = new MidiEvent(); e.firstByte = 0xB0; int value = Math.Max(0, Math.Min(maxPitchBendSensitivity, pbs.getElementA(i))); e.data = new int[] { 0x06, map[value] }; e.clock = clock; sequence.get(clock).pit.add(e); } } var pit = track.MetaText.PIT; for (int i = 0; i < pit.size(); ++i) { var clock = pit.getKeyClock(i); var e = new MidiEvent(); e.firstByte = 0xE0; var value = pit.getElementA(i) + 8192; var msb = 0x7F & value; var lsb = 0x7F & (value >> 7); e.data = new int[] { msb, lsb }; sequence.get(clock).pit.add(e); } }
public void test() { var sequence = new EventQueueSequence(); { Assert.False( sequence.keyIterator().hasNext() ); } { var queue = sequence.get( 0 ); var iterator = sequence.keyIterator(); Assert.True( iterator.hasNext() ); Assert.AreEqual( 0, iterator.next() ); Assert.False( iterator.hasNext() ); } }
/// <summary> /// 歌手変更イベントを、イベントキューに追加する /// </summary> /// <param name="queueSequence">追加対象のイベントキュー</param> /// <param name="track">歌手変更イベントを取り出すトラック</param> /// <param name="start">時間区間の開始位置</param> /// <param name="end">時間区間の終了位置</param> private void addSingerEvents(EventQueueSequence queueSequence, VsqTrack track, int start, int end) { var iterator = track.getSingerEventIterator(start, end); while (iterator.hasNext()) { var item = iterator.next(); if (item.ID.IconHandle == null) { continue; } int program = item.ID.IconHandle.Program; var singer = mDriver.createSingerEvent(program); if (0 < singer.Length) { var queue = queueSequence.get(item.Clock); queue.param.addAll(Arrays.asList(singer)); } } }
/// <summary> /// イベントキューを生成する /// </summary> /// <param name="vsq"></param> /// <param name="trackIndex"></param> /// <returns></returns> protected EventQueueSequence generateMidiEvent(VsqFileEx vsq, int trackIndex) { var result = new EventQueueSequence(); var track = vsq.Track[trackIndex]; appendNoteEvent(track, result); foreach (var item in track.MetaText.Events.Events) { reflectNoteEventPitch(item, track.MetaText.PIT, track.MetaText.PBS, vsq.TempoTable); } appendPitchEvent(track, result); return(result); }
public void begin(long total_samples, WorkerState state) { var mDriver = getDriver(); #if DEBUG sout.println("AquesToneRenderingRunner#begin; (mDriver==null)=" + (mDriver == null)); String file = System.IO.Path.Combine(System.Windows.Forms.Application.StartupPath, "AquesToneWaveGenerator.txt"); log = new System.IO.StreamWriter(file); log.AutoFlush = true; #endif if (mDriver == null) { #if DEBUG log.WriteLine("mDriver==null"); log.Close(); #endif exitBegin(); state.reportComplete(); return; } #if DEBUG sout.println("AquesToneRenderingRunner#begin; mDriver.loaded=" + mDriver.loaded); #endif if (!mDriver.loaded) { #if DEBUG log.WriteLine("mDriver.loaded=" + mDriver.loaded); log.Close(); #endif exitBegin(); state.reportComplete(); return; } mRunning = true; //mAbortRequired = false; mTotalSamples = total_samples; #if DEBUG sout.println("AquesToneWaveGenerator#begin; mTotalSamples=" + mTotalSamples); log.WriteLine("mTotalSamples=" + mTotalSamples); log.WriteLine("mTrimRemain=" + mTrimRemain); #endif VsqTrack track = mVsq.Track.get(mTrack); int BUFLEN = mSampleRate / 10; double[] left = new double[BUFLEN]; double[] right = new double[BUFLEN]; long saProcessed = 0; int saRemain = 0; int lastClock = 0; // 最後に処理されたゲートタイム // 最初にダミーの音を鳴らす // (最初に入るノイズを回避するためと、前回途中で再生停止した場合に無音から始まるようにするため) mDriver.resetAllParameters(); mDriver.process(left, right, BUFLEN); MidiEvent f_noteon = new MidiEvent(); f_noteon.firstByte = 0x90; f_noteon.data = new int[] { 0x40, 0x40 }; f_noteon.clock = 0; mDriver.send(new MidiEvent[] { f_noteon }); mDriver.process(left, right, BUFLEN); MidiEvent f_noteoff = new MidiEvent(); f_noteoff.firstByte = 0x80; f_noteoff.data = new int[] { 0x40, 0x7F }; mDriver.send(new MidiEvent[] { f_noteoff }); for (int i = 0; i < 3; i++) { mDriver.process(left, right, BUFLEN); } #if DEBUG log.WriteLine("pre-process done"); log.WriteLine("-----------------------------------------------------"); VsqTrack vsq_track = mVsq.Track.get(mTrack); for (Iterator <VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); log.WriteLine("c" + item.Clock + "; " + item.ID.LyricHandle.L0.Phrase); } #endif // レンダリング開始位置での、パラメータの値をセットしておく for (Iterator <VsqEvent> itr = track.getNoteEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); #if DEBUG sout.println("AquesToneWaveGenerator#begin; item.Clock=" + item.Clock); log.WriteLine("*********************************************************"); log.WriteLine("item.Clock=" + item.Clock); #endif long saNoteStart = (long)(mVsq.getSecFromClock(item.Clock) * mSampleRate); long saNoteEnd = (long)(mVsq.getSecFromClock(item.Clock + item.ID.getLength()) * mSampleRate); #if DEBUG log.WriteLine("saNoteStart=" + saNoteStart + "; saNoteEnd=" + saNoteEnd); #endif EventQueueSequence list = generateMidiEvent(mVsq, mTrack, lastClock, item.Clock + item.ID.getLength()); lastClock = item.Clock + item.ID.Length + 1; for (Iterator <Integer> itr2 = list.keyIterator(); itr2.hasNext();) { // まず直前までの分を合成 Integer clock = itr2.next(); #if DEBUG log.WriteLine("-------------------------------------------------------"); sout.println("AquesToneWaveGenerator#begin; clock=" + clock); #endif long saStart = (long)(mVsq.getSecFromClock(clock) * mSampleRate); saRemain = (int)(saStart - saProcessed); #if DEBUG log.WriteLine("saStart=" + saStart); log.WriteLine("saRemain=" + saRemain); #endif while (saRemain > 0) { if (state.isCancelRequested()) { goto heaven; } int len = saRemain > BUFLEN ? BUFLEN : saRemain; mDriver.process(left, right, len); waveIncoming(left, right, len); saRemain -= len; saProcessed += len; state.reportProgress(saProcessed); //mTotalAppend += len; <- waveIncomingで計算されるので } // MIDiイベントを送信 MidiEventQueue queue = list.get(clock); // まずnoteoff boolean noteoff_send = false; if (queue.noteoff.size() > 0) { #if DEBUG for (int i = 0; i < queue.noteoff.size(); i++) { String str = ""; MidiEvent itemi = queue.noteoff.get(i); str += "0x" + PortUtil.toHexString(itemi.firstByte, 2) + " "; for (int j = 0; j < itemi.data.Length; j++) { str += "0x" + PortUtil.toHexString(itemi.data[j], 2) + " "; } sout.println(typeof(AquesToneWaveGenerator) + "#begin; noteoff; " + str); } #endif mDriver.send(queue.noteoff.toArray(new MidiEvent[] { })); noteoff_send = true; } // parameterの変更 if (queue.param.size() > 0) { for (Iterator <ParameterEvent> itr3 = queue.param.iterator(); itr3.hasNext();) { ParameterEvent pe = itr3.next(); #if DEBUG sout.println(typeof(AquesToneWaveGenerator) + "#begin; param; index=" + pe.index + "; value=" + pe.value); #endif mDriver.setParameter(pe.index, pe.value); } } // ついでnoteon if (queue.noteon.size() > 0) { // 同ゲートタイムにピッチベンドも指定されている場合、同時に送信しないと反映されないようだ! if (queue.pit.size() > 0) { queue.noteon.addAll(queue.pit); queue.pit.clear(); } #if DEBUG for (int i = 0; i < queue.noteon.size(); i++) { String str = ""; MidiEvent itemi = queue.noteon.get(i); str += "0x" + PortUtil.toHexString(itemi.firstByte, 2) + " "; for (int j = 0; j < itemi.data.Length; j++) { str += "0x" + PortUtil.toHexString(itemi.data[j], 2) + " "; } sout.println(typeof(AquesToneWaveGenerator) + "#begin; noteon; " + str); } #endif mDriver.send(queue.noteon.toArray(new MidiEvent[] { })); } // PIT if (queue.pit.size() > 0 && !noteoff_send) { #if DEBUG for (int i = 0; i < queue.pit.size(); i++) { String str = ""; MidiEvent itemi = queue.pit.get(i); str += "0x" + PortUtil.toHexString(itemi.firstByte, 2) + " "; for (int j = 0; j < itemi.data.Length; j++) { str += "0x" + PortUtil.toHexString(itemi.data[j], 2) + " "; } sout.println(typeof(AquesToneWaveGenerator) + "#begin; pit; " + str); } #endif mDriver.send(queue.pit.toArray(new MidiEvent[] { })); } if (mDriver.getUi(mMainWindow) != null) { mDriver.getUi(mMainWindow).invalidateUi(); } } } // totalSamplesに足りなかったら、追加してレンダリング saRemain = (int)(mTotalSamples - mTotalAppend); #if DEBUG sout.println("AquesToneRenderingRunner#run; totalSamples=" + mTotalSamples + "; mTotalAppend=" + mTotalAppend + "; saRemain=" + saRemain); #endif while (saRemain > 0) { if (state.isCancelRequested()) { goto heaven; } int len = saRemain > BUFLEN ? BUFLEN : saRemain; mDriver.process(left, right, len); waveIncoming(left, right, len); saRemain -= len; saProcessed += len; state.reportProgress(saProcessed); //mTotalAppend += len; } heaven: #if DEBUG log.Close(); #endif exitBegin(); state.reportComplete(); }
/// <summary> /// イベントキューを生成する /// </summary> /// <param name="vsq"></param> /// <param name="trackIndex"></param> /// <returns></returns> protected EventQueueSequence generateMidiEvent( VsqFileEx vsq, int trackIndex ) { var result = new EventQueueSequence(); var track = vsq.Track[trackIndex]; appendNoteEvent( track, result ); foreach ( var item in track.MetaText.Events.Events ) { reflectNoteEventPitch( item, track.MetaText.PIT, track.MetaText.PBS, vsq.TempoTable ); } appendPitchEvent( track, result ); return result; }
/// <summary> /// 音符の note on/off のためのイベントを作成し、イベントキューに追加する /// </summary> /// <param name="track">生成元のトラック</param> /// <param name="result">生成したイベントの追加先</param> private void appendNoteEvent( VsqTrack track, EventQueueSequence result ) { foreach ( var item in track.MetaText.Events.Events ) { if ( item.ID.type != VsqIDType.Anote ) continue; var note = item.ID.Note; { var clock = item.Clock; var queue = result.get( clock ); var noteOn = driver_.createNoteOnEvent( item.ID.Note, item.ID.Dynamics, item.ID.LyricHandle.L0.Phrase ); queue.noteon.AddRange( noteOn ); } { var clock = item.Clock + item.ID.Length; var queue = result.get( clock ); var noteOff = createNoteOffEvent( clock, item.ID.Note ); queue.noteoff.add( noteOff ); } } }
/// <summary> /// ピッチとピッチベンドセンシティビティをイベントキューに追加する /// </summary> /// <param name="track"></param> /// <param name="sequence"></param> private void appendPitchEvent( VsqTrack track, EventQueueSequence sequence ) { // 実際に AquesTone2 に送信する pbs の値と、pbs カーブに入っている値とのマップ const int maxPitchBendSensitivity = 23; int[] map = new int[maxPitchBendSensitivity + 1] { 0, 5, 15, 35, 44, 54, 64, 74, 84, 93, 103, 113, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, }; var pbs = track.MetaText.PBS; for ( int i = 0; i < pbs.size(); ++i ) { var clock = pbs.getKeyClock( i ); { // RPN MSB = 0x00 var e = new MidiEvent(); e.firstByte = 0xB0; e.data = new int[] { 0x65, 0x00 }; e.clock = clock; sequence.get( clock ).pit.add( e ); } { // RPN LSB = 0x00 var e = new MidiEvent(); e.firstByte = 0xB0; e.data = new int[] { 0x64, 0x00 }; e.clock = clock; sequence.get( clock ).pit.add( e ); } { // RPN data MSB var e = new MidiEvent(); e.firstByte = 0xB0; int value = Math.Max( 0, Math.Min( maxPitchBendSensitivity, pbs.getElementA( i ) ) ); e.data = new int[] { 0x06, map[value] }; e.clock = clock; sequence.get( clock ).pit.add( e ); } } var pit = track.MetaText.PIT; for ( int i = 0; i < pit.size(); ++i ) { var clock = pit.getKeyClock( i ); var e = new MidiEvent(); e.firstByte = 0xE0; var value = pit.getElementA( i ) + 8192; var msb = 0x7F & value; var lsb = 0x7F & (value >> 7); e.data = new int[] { msb, lsb }; sequence.get( clock ).pit.add( e ); } }
/// <summary> /// /// </summary> /// <param name="vsq"></param> /// <param name="track"></param> /// <param name="clock_start"></param> /// <param name="clock_end"></param> /// <returns></returns> protected override EventQueueSequence generateMidiEvent(VsqFileEx vsq, int track, int clock_start, int clock_end) { EventQueueSequence list = new EventQueueSequence(); VsqTrack t = vsq.Track.get(track); addSingerEvents(list, t, clock_start, clock_end); // ノートon, off Vector <Point> pit_send = new Vector <Point>(); // PITが追加されたゲートタイム。音符先頭の分を重複して送信するのを回避するために必要。 VsqBPList pit = t.getCurve("pit"); VsqBPList pbs = t.getCurve("pbs"); VsqBPList dyn = t.getCurve("dyn"); VsqBPList bre = t.getCurve("bre"); VsqBPList cle = t.getCurve("cle"); VsqBPList por = t.getCurve("por"); for (Iterator <VsqEvent> itr = t.getNoteEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); int endclock = item.Clock + item.ID.getLength(); boolean contains_start = clock_start <= item.Clock && item.Clock <= clock_end; boolean contains_end = clock_start <= endclock && endclock <= clock_end; if (contains_start || contains_end) { if (contains_start) { #region contains_start // noteonのゲートタイムが,範囲に入っている // noteon MIDIイベントを作成 MidiEvent[] noteOnEvents = mDriver.createNoteOnEvent(item.ID.Note, item.ID.Dynamics, item.ID.LyricHandle.L0.Phrase); if (noteOnEvents.Length > 0) { MidiEventQueue queue = list.get(item.Clock); Vector <MidiEvent> add = Arrays.asList(noteOnEvents); queue.noteon.addAll(add); pit_send.add(new Point(item.Clock, item.Clock)); } /* 音符頭で設定するパラメータ */ // Release MidiEventQueue q = list.get(item.Clock); String strRelease = VsqFileEx.getEventTag(item, VsqFileEx.TAG_VSQEVENT_AQUESTONE_RELEASE); int release = 64; try { release = int.Parse(strRelease); } catch (Exception ex) { Logger.write(typeof(AquesToneWaveGenerator) + ".generateMidiEvent; ex=" + ex + "\n"); release = 64; } ParameterEvent pe = new ParameterEvent(); pe.index = mDriver.releaseParameterIndex; pe.value = release / 127.0f; q.param.add(pe); // dyn int dynAtStart = dyn.getValue(item.Clock); ParameterEvent peDyn = new ParameterEvent(); peDyn.index = mDriver.volumeParameterIndex; peDyn.value = (float)(dynAtStart - dyn.getMinimum()) / (float)(dyn.getMaximum() - dyn.getMinimum()); q.param.add(peDyn); // bre int breAtStart = bre.getValue(item.Clock); ParameterEvent peBre = new ParameterEvent(); peBre.index = mDriver.haskyParameterIndex; peBre.value = (float)(breAtStart - bre.getMinimum()) / (float)(bre.getMaximum() - bre.getMinimum()); q.param.add(peBre); // cle int cleAtStart = cle.getValue(item.Clock); ParameterEvent peCle = new ParameterEvent(); peCle.index = mDriver.resonancParameterIndex; peCle.value = (float)(cleAtStart - cle.getMinimum()) / (float)(cle.getMaximum() - cle.getMinimum()); q.param.add(peCle); // por int porAtStart = por.getValue(item.Clock); ParameterEvent pePor = new ParameterEvent(); pePor.index = mDriver.portaTimeParameterIndex; pePor.value = (float)(porAtStart - por.getMinimum()) / (float)(por.getMaximum() - por.getMinimum()); q.param.add(pePor); #endregion } // ビブラート // ビブラートが存在する場合、PBSは勝手に変更する。 if (item.ID.VibratoHandle == null) { if (contains_start) { // 音符頭のPIT, PBSを強制的に指定 int notehead_pit = pit.getValue(item.Clock); MidiEvent pit0 = getPitMidiEvent(notehead_pit); MidiEventQueue queue = list.get(item.Clock); queue.pit.clear(); queue.pit.add(pit0); int notehead_pbs = pbs.getValue(item.Clock); ParameterEvent pe = new ParameterEvent(); pe.index = mDriver.bendLblParameterIndex; pe.value = notehead_pbs / 13.0f; queue.param.add(pe); } } else { int delta_clock = 5; //ピッチを取得するクロック間隔 int tempo = 120; double sec_start_act = vsq.getSecFromClock(item.Clock); double sec_end_act = vsq.getSecFromClock(item.Clock + item.ID.getLength()); double delta_sec = delta_clock / (8.0 * tempo); //ピッチを取得する時間間隔 float pitmax = 0.0f; int st = item.Clock; if (st < clock_start) { st = clock_start; } int end = item.Clock + item.ID.getLength(); if (clock_end < end) { end = clock_end; } pit_send.add(new Point(st, end)); // ビブラートが始まるまでのピッチを取得 double sec_vibstart = vsq.getSecFromClock(item.Clock + item.ID.VibratoDelay); int pit_count = (int)((sec_vibstart - sec_start_act) / delta_sec); TreeMap <Integer, Float> pit_change = new TreeMap <Integer, Float>(); for (int i = 0; i < pit_count; i++) { double gtime = sec_start_act + delta_sec * i; int clock = (int)vsq.getClockFromSec(gtime); float pvalue = (float)t.getPitchAt(clock); pitmax = Math.Max(pitmax, Math.Abs(pvalue)); pit_change.put(clock, pvalue); } // ビブラート部分のピッチを取得 Vector <PointD> ret = new Vector <PointD>(); Iterator <PointD> itr2 = new VibratoPointIteratorBySec( vsq, item.ID.VibratoHandle.getRateBP(), item.ID.VibratoHandle.getStartRate(), item.ID.VibratoHandle.getDepthBP(), item.ID.VibratoHandle.getStartDepth(), item.Clock + item.ID.VibratoDelay, item.ID.getLength() - item.ID.VibratoDelay, (float)delta_sec); for ( ; itr2.hasNext();) { PointD p = itr2.next(); float gtime = (float)p.getX(); int clock = (int)vsq.getClockFromSec(gtime); float pvalue = (float)(t.getPitchAt(clock) + p.getY() * 100.0); pitmax = Math.Max(pitmax, Math.Abs(pvalue)); pit_change.put(clock, pvalue); } // ピッチベンドの最大値を実現するのに必要なPBS int required_pbs = (int)Math.Ceiling(pitmax / 100.0); #if DEBUG sout.println("AquesToneRenderingRunner#generateMidiEvent; required_pbs=" + required_pbs); #endif if (required_pbs > 13) { required_pbs = 13; } MidiEventQueue queue = list.get(item.Clock); ParameterEvent pe = new ParameterEvent(); pe.index = mDriver.bendLblParameterIndex; pe.value = required_pbs / 13.0f; queue.param.add(pe); // PITを順次追加 for (Iterator <Integer> itr3 = pit_change.keySet().iterator(); itr3.hasNext();) { Integer clock = itr3.next(); if (clock_start <= clock && clock <= clock_end) { float pvalue = pit_change.get(clock); int pit_value = (int)(8192.0 / (double)required_pbs * pvalue / 100.0); MidiEventQueue q = list.get(clock); MidiEvent me = getPitMidiEvent(pit_value); q.pit.clear(); q.pit.add(me); } else if (clock_end < clock) { break; } } } //pit_send.add( pit_send_p ); // noteoff MIDIイベントを作成 if (contains_end) { MidiEvent noteoff = new MidiEvent(); noteoff.firstByte = 0x80; noteoff.data = new int[] { item.ID.Note, 0x40 }; // ここのvel Vector <MidiEvent> a_noteoff = Arrays.asList(new MidiEvent[] { noteoff }); MidiEventQueue q = list.get(endclock); q.noteoff.addAll(a_noteoff); pit_send.add(new Point(endclock, endclock)); // PITの送信を抑制するために必要 } } if (clock_end < item.Clock) { break; } } // pitch bend sensitivity // RPNで送信するのが上手くいかないので、parameterを直接いぢる if (pbs != null) { int keycount = pbs.size(); for (int i = 0; i < keycount; i++) { int clock = pbs.getKeyClock(i); if (clock_start <= clock && clock <= clock_end) { int value = pbs.getElementA(i); ParameterEvent pbse = new ParameterEvent(); pbse.index = mDriver.bendLblParameterIndex; pbse.value = value / 13.0f; MidiEventQueue queue = list.get(clock); queue.param.add(pbse); } else if (clock_end < clock) { break; } } } // pitch bend if (pit != null) { int keycount = pit.size(); for (int i = 0; i < keycount; i++) { int clock = pit.getKeyClock(i); if (clock_start <= clock && clock <= clock_end) { boolean contains = false; for (Iterator <Point> itr = pit_send.iterator(); itr.hasNext();) { Point p = itr.next(); if (p.x <= clock && clock <= p.y) { contains = true; break; } } if (contains) { continue; } int value = pit.getElementA(i); MidiEvent pbs0 = getPitMidiEvent(value); MidiEventQueue queue = list.get(clock); queue.pit.clear(); queue.pit.add(pbs0); } else if (clock_end < clock) { break; } } } appendParameterEvents(list, dyn, mDriver.volumeParameterIndex, clock_start, clock_end); appendParameterEvents(list, bre, mDriver.haskyParameterIndex, clock_start, clock_end); appendParameterEvents(list, cle, mDriver.resonancParameterIndex, clock_start, clock_end); appendParameterEvents(list, por, mDriver.portaTimeParameterIndex, clock_start, clock_end); return(list); }