public AttackVariation convertFrom(string value) { if (value.Equals(new AttackVariation().mDescription)) { return(new AttackVariation()); } else { SynthesizerType type = SynthesizerType.VOCALOID2; VsqFileEx vsq = AppManager.getVsqFile(); if (vsq != null) { string svalue = (string)value; foreach (var aconfig in VocaloSysUtil.attackConfigIterator(type)) { string display_string = aconfig.getDisplayString(); if (svalue.Equals(display_string)) { return(new AttackVariation(display_string)); } } } return(new AttackVariation()); } }
/// <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 VibratoPointIteratorBySec(VsqFileEx vsq, VibratoBPList rate, int start_rate, VibratoBPList depth, int start_depth, int clock_start, int clock_width, float sec_resolution) { this.vsq = vsq; this.rate = rate; this.start_rate = start_rate; this.depth = depth; this.start_depth = start_depth; this.clock_start = clock_start; this.clock_width = clock_width; this.sec_resolution = sec_resolution; sec0 = vsq.getSecFromClock(clock_start); sec1 = vsq.getSecFromClock(clock_start + clock_width); count = (int)((sec1 - sec0) / sec_resolution); phase = 0; start_rate = rate.getValue(0.0f, start_rate); start_depth = depth.getValue(0.0f, start_depth); amplitude = start_depth * 2.5f / 127.0f / 2.0f; // ビブラートの振幅。 period = getPeriodFromRate(start_rate); //ビブラートの周期、秒 omega = (float)(2.0 * Math.PI / period); // 角速度(rad/sec) sec = sec0; fadewidth = (float)(sec1 - sec0) * 0.2f; }
/// <summary> /// 初期化メソッド /// </summary> /// <param name="vsq"></param> /// <param name="track"></param> /// <param name="start_clock"></param> /// <param name="end_clock"></param> public void init(VsqFileEx vsq, int track, int start_clock, int end_clock, int sample_rate) { mSampleRate = sample_rate; #if DEBUG sout.println("WaveSenderDriver#init; sample_rate=" + sample_rate); #endif }
/// <summary> /// 選択中のアイテムが編集された場合、編集にあわせてオブジェクトを更新する。 /// </summary> public void updateSelectedEventInstance() { VsqFileEx vsq = AppManager.getVsqFile(); if (vsq == null) { return; } int selected = AppManager.getSelected(); VsqTrack vsq_track = vsq.Track[selected]; for (int i = 0; i < mEvents.Count; i++) { SelectedEventEntry item = mEvents[i]; VsqEvent ev = null; if (item.track == selected) { int internal_id = item.original.InternalID; ev = vsq_track.findEventFromID(internal_id); } if (ev != null) { mEvents[i] = new SelectedEventEntry(selected, ev, (VsqEvent)ev.clone()); } else { mEvents.RemoveAt(i); i--; } } }
/// <summary> /// スクリプトの本体 /// </summary> /// <param name="vsq"></param> /// <returns></returns> public static ScriptReturnStatus Edit( VsqFileEx vsq ) { int selected = AppManager.getSelected(); VsqTrack vsq_track = vsq.Track.get( selected ); RendererKind kind = VsqFileEx.getTrackRendererKind( vsq_track ); if ( kind != RendererKind.UTAU ) { return ScriptReturnStatus.NOT_EDITED; } bool edited = false; for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) { SelectedEventEntry item = itr.next(); VsqEvent original = item.original; if ( original.ID.type != VsqIDType.Anote ) { continue; } VsqEvent singer = vsq_track.getSingerEventAt( original.Clock ); SingerConfig sc = AppManager.getSingerInfoUtau( singer.ID.IconHandle.Language, singer.ID.IconHandle.Program ); if ( sc != null && AppManager.mUtauVoiceDB.containsKey( sc.VOICEIDSTR ) ) { string phrase = original.ID.LyricHandle.L0.Phrase; UtauVoiceDB db = AppManager.mUtauVoiceDB.get( sc.VOICEIDSTR ); OtoArgs oa = db.attachFileNameFromLyric( phrase ); VsqEvent editing = vsq_track.findEventFromID( original.InternalID ); if ( editing.UstEvent == null ) { editing.UstEvent = new UstEvent(); } editing.UstEvent.setVoiceOverlap( oa.msOverlap ); editing.UstEvent.setPreUtterance( oa.msPreUtterance ); edited = true; } } return edited ? ScriptReturnStatus.EDITED : ScriptReturnStatus.NOT_EDITED; }
public static ScriptReturnStatus Edit(VsqFileEx vsq) { UtauPluginManager dialog = new UtauPluginManager(); dialog.ShowDialog(); return(ScriptReturnStatus.NOT_EDITED); }
/// <summary> /// 指定したVSQの指定した位置に,テンポの挿入を試みます. /// 既存のテンポがある場合,値が上書きされます /// </summary> /// <param name="vsq">挿入対象のVSQ</param> /// <param name="clock">挿入位置</param> /// <param name="tempo">楽譜表記上のテンポ.BPS</param> private static void insertTempoInto(VsqFileEx vsq, int clock, float t) { // clockの位置にテンポ変更があるかどうか? int num_tempo = vsq.TempoTable.size(); int index = -1; for (int j = 0; j < num_tempo; j++) { TempoTableEntry itemj = vsq.TempoTable[j]; if (itemj.Clock == clock) { index = j; break; } } int tempo = (int)(60e6 / t); if (index >= 0) { // clock位置に既存のテンポ変更がある場合,テンポ値を変更 TempoTableEntry itemj = vsq.TempoTable[index]; itemj.Tempo = tempo; } else { // 既存のものはないので新規に追加 vsq.TempoTable.Add(new TempoTableEntry(clock, tempo, 0.0)); } // テンポテーブルを更新 vsq.TempoTable.updateTempoInfo(); }
/// <summary> /// パレットツールを実行します /// </summary> /// <param name="id">実行するパレットツールのID</param> /// <param name="track">編集対象のトラック番号</param> /// <param name="vsq_event_intrenal_ids">編集対象のInternalIDのリスト</param> /// <param name="button">パレットツールが押し下げられた時のマウスボタンの種類</param> /// <returns>パレットツールによって編集が加えられた場合true。そうでなければfalse(パレットツールがエラーを起こした場合も含む)。</returns> public static boolean invokePaletteTool( String id, int track, int[] vsq_event_intrenal_ids, MouseButtons button ) { if ( loadedTools.containsKey( id ) ) { VsqFileEx vsq = AppManager.getVsqFile(); VsqTrack item = (VsqTrack)vsq.Track.get( track ).clone(); Object objPal = loadedTools.get( id ); if ( objPal == null ) { return false; } if ( !(objPal is IPaletteTool) ) { return false; } IPaletteTool pal = (IPaletteTool)objPal; boolean edited = false; try { edited = pal.edit( item, vsq_event_intrenal_ids, button ); } catch ( Exception ex ) { AppManager.showMessageBox( PortUtil.formatMessage( _( "Palette tool '{0}' reported an error.\nPlease copy the exception text and report it to developper." ), id ), "Error", cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_ERROR_MESSAGE ); serr.println( typeof( PaletteToolServer ) + ".invokePaletteTool; ex=" + ex ); edited = false; } if ( edited ) { CadenciiCommand run = VsqFileEx.generateCommandTrackReplace( track, item, vsq.AttachedCurves.get( track - 1 ) ); AppManager.editHistory.register( vsq.executeCommand( run ) ); } return edited; } else { return false; } }
/// <summary> /// ソロ,ミュートのボタンのチェック状態を更新します /// </summary> private void updateSoloMute() { VsqFileEx vsq = AppManager.getVsqFile(); if (vsq == null) { return; } // マスター bool masterMuted = vsq.getMasterMute(); volumeMaster.setMuted(masterMuted); // VSQのトラック bool soloSpecificationExists = false; // 1トラックでもソロ指定があればtrue for (int i = 1; i < vsq.Track.Count; i++) { if (vsq.getSolo(i)) { soloSpecificationExists = true; break; } } for (int track = 1; track < vsq.Track.Count; track++) { if (soloSpecificationExists) { if (vsq.getSolo(track)) { m_tracker[track - 1].setSolo(true); m_tracker[track - 1].setMuted(masterMuted ? true : vsq.getMute(track)); } else { m_tracker[track - 1].setSolo(false); m_tracker[track - 1].setMuted(true); } } else { m_tracker[track - 1].setSolo(vsq.getSolo(track)); m_tracker[track - 1].setMuted(masterMuted ? true : vsq.getMute(track)); } } // BGM int offset = vsq.Track.Count - 1; for (int i = 0; i < vsq.BgmFiles.Count; i++) { m_tracker[offset + i].setMuted(masterMuted ? true : vsq.BgmFiles[i].mute == 1); } this.Refresh(); }
public UtauSymbolSplitor(VsqFileEx mVsq, VsqEvent curEvent, Dictionary <int, double> PitchBrust, List <VsqEvent> VibstrBrustEvents, cadencii.utau.UtauVoiceDB db) { oriPitchBrust = PitchBrust; oriVibstrBrustEvents = VibstrBrustEvents; oriEvent = curEvent; dstVibstrBrustEvents.Add(oriEvent, oriVibstrBrustEvents); dstPitchBrust.Add(oriEvent, oriPitchBrust); dstParentTable.Add(oriEvent, oriEvent); vdb = db; this.mVsq = mVsq; }
public List <Object> getStandardValues() { SynthesizerType type = SynthesizerType.VOCALOID2; VsqFileEx vsq = AppManager.getVsqFile(); List <Object> list = new List <Object>(); list.Add(new AttackVariation()); foreach (var aconfig in VocaloSysUtil.attackConfigIterator(type)) { list.Add(new AttackVariation(aconfig.getDisplayString())); } return(list);//new StandardValuesCollection( list.toArray( new AttackVariation[] { } ) ); }
/// <summary> /// 指定したBGMのボリュームのUIコントロールを取得します /// </summary> /// <param name="index"></param> /// <returns></returns> public VolumeTracker getVolumeTrackerBgm(int index) { VsqFileEx vsq = AppManager.getVsqFile(); int offset = vsq.Track.Count - 1; if (0 <= index + offset && index + offset < m_tracker.Count) { return(m_tracker[index + offset]); } else { return(null); } }
public void init( VsqFileEx sequence, int track, int start_clock, int end_clock, int sample_rate ) { sequence_ = (VsqFileEx)sequence.Clone(); sequence_.updateTotalClocks(); sequence_.removePart( end_clock, sequence_.TotalClocks ); sequence_.removePart( 0, start_clock ); sequence_.updateTotalClocks(); sequence_.updateTempoInfo(); sequence_.updateTimesigInfo(); track_index_ = track; sample_rate_ = sample_rate; is_running_ = false; position_ = 0; }
public void init(VsqFileEx sequence, int track, int start_clock, int end_clock, int sample_rate) { sequence_ = (VsqFileEx)sequence.Clone(); sequence_.updateTotalClocks(); sequence_.removePart(end_clock, sequence_.TotalClocks); sequence_.removePart(0, start_clock); sequence_.updateTotalClocks(); sequence_.updateTempoInfo(); sequence_.updateTimesigInfo(); track_index_ = track; sample_rate_ = sample_rate; is_running_ = false; position_ = 0; }
public void handleUndoRedo_Click(Object sender, EventArgs e) { if (sender == btnUndo) { AppManager.undo(); } else if (sender == btnRedo) { AppManager.redo(); } else { return; } VsqFileEx vsq = AppManager.getVsqFile(); bool exists = false; if (vsq != null) { exists = vsq.Track[AppManager.getSelected()].getCurve(m_curve.getName()).findElement(m_editing_id).index >= 0; } #if DEBUG sout.println("FormCurvePointEdit#handleUndoRedo_Click; exists=" + exists); #endif txtDataPointClock.Enabled = exists; txtDataPointValue.Enabled = exists; btnApply.Enabled = exists; btnBackward.Enabled = exists; btnBackward2.Enabled = exists; btnBackward3.Enabled = exists; btnForward.Enabled = exists; btnForward2.Enabled = exists; btnForward3.Enabled = exists; if (exists) { AppManager.itemSelection.clearPoint(); AppManager.itemSelection.addPoint(m_curve, m_editing_id); } if (mMainWindow != null) { mMainWindow.updateDrawObjectList(); mMainWindow.refreshScreen(); } btnUndo.Enabled = AppManager.editHistory.hasUndoHistory(); btnRedo.Enabled = AppManager.editHistory.hasRedoHistory(); }
public FormBezierPointEditController( TrackSelector parent, CurveType curve_type, int selected_chain_id, int selected_point_id) { ui = (FormBezierPointEditUi) new FormBezierPointEditUiImpl(this); applyLanguage(); m_parent = parent; m_curve_type = curve_type; m_track = AppManager.getSelected(); m_chain_id = selected_chain_id; m_point_id = selected_point_id; bool found = false; VsqFileEx vsq = AppManager.getVsqFile(); BezierCurves attached = vsq.AttachedCurves.get(m_track - 1); List <BezierChain> chains = attached.get(m_curve_type); for (int i = 0; i < chains.Count; i++) { if (chains[i].id == m_chain_id) { found = true; break; } } if (!found) { return; } bool smooth = false; foreach (var bp in attached.getBezierChain(m_curve_type, m_chain_id).points) { if (bp.getID() == m_point_id) { m_point = bp; smooth = (bp.getControlLeftType() != BezierControlType.None) || (bp.getControlRightType() != BezierControlType.None); break; } } updateStatus(); }
/// <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> /// 指定したトラックのボリュームのUIコントロールを取得します /// </summary> /// <param name="track"></param> /// <returns></returns> public VolumeTracker getVolumeTracker(int track) { VsqFileEx vsq = AppManager.getVsqFile(); if (1 <= track && track < vsq.Track.Count && 0 <= track - 1 && track - 1 < m_tracker.Count) { return(m_tracker[track - 1]); } else if (track == 0) { return(volumeMaster); } else { return(null); } }
public VibratoVariation convertFrom(string value) { if (value.Equals(VibratoVariation.empty.description)) { return(new VibratoVariation(VibratoVariation.empty.description)); } else { if (AppManager.editorConfig.UseUserDefinedAutoVibratoType) { int size = AppManager.editorConfig.AutoVibratoCustom.Count; for (int i = 0; i < size; i++) { string display_string = AppManager.editorConfig.AutoVibratoCustom[i].getDisplayString(); if (value.Equals(display_string)) { return(new VibratoVariation(display_string)); } } } else { SynthesizerType type = SynthesizerType.VOCALOID2; VsqFileEx vsq = AppManager.getVsqFile(); if (vsq != null) { /* * RendererKind kind = VsqFileEx.getTrackRendererKind(vsq.Track[AppManager.getSelected()]); * if (kind == RendererKind.VOCALOID1) { * type = SynthesizerType.VOCALOID1; * }*/ foreach (var vconfig in VocaloSysUtil.vibratoConfigIterator(type)) { string display_string = vconfig.getDisplayString(); if (value.Equals(display_string)) { return(new VibratoVariation(display_string)); } } } } return(new VibratoVariation(VibratoVariation.empty.description)); } }
/// <summary> /// スクリプトの本体 /// </summary> /// <param name="vsq"></param> /// <returns></returns> public static ScriptReturnStatus Edit(VsqFileEx vsq) { int selected = AppManager.getSelected(); VsqTrack vsq_track = vsq.Track[selected]; RendererKind kind = VsqFileEx.getTrackRendererKind(vsq_track); if (kind != RendererKind.UTAU) { return(ScriptReturnStatus.NOT_EDITED); } bool edited = false; foreach (var item in AppManager.itemSelection.getEventIterator()) { VsqEvent original = item.original; if (original.ID.type != VsqIDType.Anote) { continue; } VsqEvent singer = vsq_track.getSingerEventAt(original.Clock); SingerConfig sc = AppManager.getSingerInfoUtau(singer.ID.IconHandle.Language, singer.ID.IconHandle.Program); if (sc != null && AppManager.mUtauVoiceDB.ContainsKey(sc.VOICEIDSTR)) { string phrase = original.ID.LyricHandle.L0.Phrase; UtauVoiceDB db = AppManager.mUtauVoiceDB[sc.VOICEIDSTR]; int CheckNote = original.ID.Note; if (original.UstEvent != null) { CheckNote = original.UstEvent.ReplaceNoteID > 0 ? original.UstEvent.ReplaceNoteID : original.ID.Note; } OtoArgs oa = db.attachFileNameFromLyric(phrase, CheckNote); VsqEvent editing = vsq_track.findEventFromID(original.InternalID); if (editing.UstEvent == null) { editing.UstEvent = new UstEvent(); } editing.UstEvent.setVoiceOverlap(oa.msOverlap); editing.UstEvent.setPreUtterance(oa.msPreUtterance); edited = true; } } return(edited ? ScriptReturnStatus.EDITED : ScriptReturnStatus.NOT_EDITED); }
public static ScriptReturnStatus Edit( VsqFileEx vsq ) { if ( runCount != 0 ) { return ScriptReturnStatus.NOT_EDITED; } runCount++; // 以下に,起動時に変更するパラメータを記述する // ピアノロールに合成システムの名称をオーバーレイ表示するかどうか AppManager.drawOverSynthNameOnPianoroll = true; // 再生中に,WAVE波形の描画をスキップするかどうか AppManager.skipDrawingWaveformWhenPlaying = true; // 起動時のツール.デフォルトはEditTool.PENCIL AppManager.setSelectedTool( EditTool.PENCIL ); // 音符の長さを変えたとき,ビブラート長さがどう影響を受けるかを決める. AppManager.vibratoLengthEditingRule = VibratoLengthEditingRule.PERCENTAGE; return ScriptReturnStatus.NOT_EDITED; }
public void handleResize(Object sender, EventArgs e) { VsqFileEx vsq = AppManager.getVsqFile(); int max = AppManager.getCurrentClock(); int total_clocks = vsq.TotalClocks; if (max < total_clocks) { max = total_clocks; } int min_width = (int)(max * mOverviewPixelPerClock) + this.Width; if (mDrawer.getWidth() < min_width) { lock (mDrawerSyncRoot) { mDrawer.setWidth(min_width); } updateCachedImage(); } }
/// <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 static ScriptReturnStatus Edit(VsqFileEx vsq) { if (runCount != 0) { return(ScriptReturnStatus.NOT_EDITED); } runCount++; // 以下に,起動時に変更するパラメータを記述する // ピアノロールに合成システムの名称をオーバーレイ表示するかどうか AppManager.drawOverSynthNameOnPianoroll = true; // 再生中に,WAVE波形の描画をスキップするかどうか AppManager.skipDrawingWaveformWhenPlaying = true; // 起動時のツール.デフォルトはEditTool.PENCIL AppManager.setSelectedTool(EditTool.PENCIL); // 音符の長さを変えたとき,ビブラート長さがどう影響を受けるかを決める. AppManager.vibratoLengthEditingRule = VibratoLengthEditingRule.PERCENTAGE; return(ScriptReturnStatus.NOT_EDITED); }
/// <summary> /// 初期化メソッド /// </summary> /// <param name="parameter"></param> public void init(VsqFileEx vsq, int track, int start_clock, int end_clock, int sample_rate) { getDriver().setSampleRate(sample_rate); mTrack = track; mStartClock = start_clock; mEndClock = end_clock; mSampleRate = sample_rate; this.mVsq = (VsqFileEx)vsq.clone(); this.mVsq.updateTotalClocks(); if (mEndClock < this.mVsq.TotalClocks) { this.mVsq.removePart(mEndClock, this.mVsq.TotalClocks + 480); } double end_sec = mVsq.getSecFromClock(start_clock); double start_sec = mVsq.getSecFromClock(end_clock); double trim_sec = 0.0; // レンダリング結果から省かなければならない秒数。 if (mStartClock < this.mVsq.getPreMeasureClocks()) { trim_sec = this.mVsq.getSecFromClock(mStartClock); } else { this.mVsq.removePart(mVsq.getPreMeasureClocks(), mStartClock); trim_sec = this.mVsq.getSecFromClock(this.mVsq.getPreMeasureClocks()); } this.mVsq.updateTotalClocks(); mTrimRemain = (int)(trim_sec * mSampleRate); //mTrimRemain = 0; #if DEBUG sout.println("AeuqsToneWaveGenerator#init; mTrimRemain=" + mTrimRemain); #endif }
public void updateCachedImage() { VsqFileEx vsq = AppManager.getVsqFile(); if (vsq == null) { return; } if (mMainForm == null) { return; } int max = AppManager.getCurrentClock(); int total_clocks = vsq.TotalClocks; if (max < total_clocks) { max = total_clocks; } int required_width = (int)(max * mOverviewPixelPerClock) + this.Width; updateCachedImage(required_width); }
/// <summary> /// スクリプトを実行します。 /// </summary> /// <param name="evsd"></param> public static boolean invokeScript( String id, VsqFileEx vsq ) { ScriptInvoker script_invoker = null; if ( scripts.containsKey( id ) ) { script_invoker = scripts.get( id ); } else { return false; } if ( script_invoker != null && script_invoker.scriptDelegate != null ) { try { VsqFileEx work = (VsqFileEx)vsq.clone(); ScriptReturnStatus ret = ScriptReturnStatus.ERROR; if ( script_invoker.scriptDelegate is EditVsqScriptDelegate ) { boolean b_ret = ((EditVsqScriptDelegate)script_invoker.scriptDelegate).Invoke( work ); if ( b_ret ) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if ( script_invoker.scriptDelegate is EditVsqScriptDelegateEx ) { boolean b_ret = ((EditVsqScriptDelegateEx)script_invoker.scriptDelegate).Invoke( work ); if ( b_ret ) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if ( script_invoker.scriptDelegate is EditVsqScriptDelegateWithStatus ) { ret = ((EditVsqScriptDelegateWithStatus)script_invoker.scriptDelegate).Invoke( work ); } else if ( script_invoker.scriptDelegate is EditVsqScriptDelegateExWithStatus ) { ret = ((EditVsqScriptDelegateExWithStatus)script_invoker.scriptDelegate).Invoke( work ); } else { ret = ScriptReturnStatus.ERROR; } if ( ret == ScriptReturnStatus.ERROR ) { AppManager.showMessageBox( _( "Script aborted" ), "Cadencii", cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE ); } else if ( ret == ScriptReturnStatus.EDITED ) { CadenciiCommand run = VsqFileEx.generateCommandReplace( work ); AppManager.editHistory.register( vsq.executeCommand( run ) ); } String config_file = configFileNameFromScriptFileName( script_invoker.ScriptFile ); FileOutputStream fs = null; boolean delete_xml_when_exit = false; // xmlを消すときtrue try { fs = new FileOutputStream( config_file ); script_invoker.Serializer.serialize( fs, null ); } catch ( Exception ex ) { serr.println( "AppManager#invokeScript; ex=" + ex ); delete_xml_when_exit = true; } finally { if ( fs != null ) { try { fs.close(); if ( delete_xml_when_exit ) { PortUtil.deleteFile( config_file ); } } catch ( Exception ex2 ) { serr.println( "AppManager#invokeScript; ex2=" + ex2 ); } } } return (ret == ScriptReturnStatus.EDITED); } catch ( Exception ex ) { AppManager.showMessageBox( _( "Script runtime error:" ) + " " + ex, _( "Error" ), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE ); serr.println( "AppManager#invokeScript; ex=" + ex ); } } else { AppManager.showMessageBox( _( "Script compilation failed." ), _( "Error" ), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_WARNING_MESSAGE ); } return false; }
public static ScriptReturnStatus Edit(VsqFileEx vsq) { // 選択状態のアイテムがなければ戻る if (AppManager.itemSelection.getEventCount() <= 0) { return(ScriptReturnStatus.NOT_EDITED); } // 現在のトラック int selected = AppManager.getSelected(); VsqTrack vsq_track = vsq.Track.get(selected); vsq_track.sortEvent(); // プラグイン情報の定義ファイル(plugin.txt)があるかどうかチェック string pluginTxtPath = s_plugin_txt_path; if (pluginTxtPath == "") { AppManager.showMessageBox("pluginTxtPath=" + pluginTxtPath); return(ScriptReturnStatus.ERROR); } if (!System.IO.File.Exists(pluginTxtPath)) { AppManager.showMessageBox("'" + pluginTxtPath + "' does not exists"); return(ScriptReturnStatus.ERROR); } // plugin.txtがあれば,プラグインの実行ファイルのパスを取得する System.Text.Encoding shift_jis = System.Text.Encoding.GetEncoding("Shift_JIS"); string name = ""; string exe_path = ""; using (StreamReader sr = new StreamReader(pluginTxtPath, shift_jis)) { string line = ""; while ((line = sr.ReadLine()) != null) { string[] spl = line.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (line.StartsWith("name=")) { name = spl[1]; } else if (line.StartsWith("execute=")) { exe_path = Path.Combine(Path.GetDirectoryName(pluginTxtPath), spl[1]); } } } if (exe_path == "") { return(ScriptReturnStatus.ERROR); } if (!System.IO.File.Exists(exe_path)) { AppManager.showMessageBox("'" + exe_path + "' does not exists"); return(ScriptReturnStatus.ERROR); } // 選択状態のアイテムの最初と最後がどこか調べる // clock_start, clock_endは,最終的にはPREV, NEXTを含んだ範囲を表すことになる // sel_start, sel_endはPREV, NEXTを含まない選択範囲を表す int id_start = -1; int clock_start = int.MaxValue; int id_end = -1; int clock_end = int.MinValue; int sel_start = 0; int sel_end = 0; for (Iterator <SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext();) { SelectedEventEntry item = itr.next(); if (item.original.ID.type != VsqIDType.Anote) { continue; } int clock = item.original.Clock; if (clock < clock_start) { id_start = item.original.InternalID; clock_start = clock; sel_start = clock; } clock += item.original.ID.getLength(); if (clock_end < clock) { id_end = item.original.InternalID; clock_end = clock; sel_end = clock; } } // 選択範囲の前後の音符を探す VsqEvent ve_prev = null; VsqEvent ve_next = null; VsqEvent l = null; for (Iterator <VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); if (item.InternalID == id_start) { if (l != null) { ve_prev = l; } } if (l != null) { if (l.InternalID == id_end) { ve_next = item; } } l = item; if (ve_prev != null && ve_next != null) { break; } } int next_rest_clock = -1; bool prev_is_rest = false; if (ve_prev != null) { // 直前の音符がある場合 if (ve_prev.Clock + ve_prev.ID.getLength() == clock_start) { // 接続している clock_start = ve_prev.Clock; } else { // 接続していない int new_clock_start = ve_prev.Clock + ve_prev.ID.getLength(); clock_start = new_clock_start; } } else { // 無い場合 if (vsq.getPreMeasureClocks() < clock_start) { prev_is_rest = true; } int new_clock_start = vsq.getPreMeasureClocks(); clock_start = new_clock_start; } if (ve_next != null) { // 直後の音符がある場合 if (ve_next.Clock == clock_end) { // 接続している clock_end = ve_next.Clock + ve_next.ID.getLength(); } else { // 接続していない next_rest_clock = clock_end; clock_end = ve_next.Clock; } } // 作業用のVSQに,選択範囲のアイテムを格納 VsqFileEx v = (VsqFileEx)vsq.clone();// new VsqFile( "Miku", 1, 4, 4, 500000 ); // 選択トラックだけ残して他を削る for (int i = 1; i < selected; i++) { v.Track.removeElementAt(1); } for (int i = selected + 1; i < v.Track.size(); i++) { v.Track.removeElementAt(selected + 1); } // 選択トラックの音符を全消去する VsqTrack v_track = v.Track.get(1); v_track.MetaText.getEventList().clear(); for (Iterator <VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext();) { VsqEvent item = itr.next(); if (clock_start <= item.Clock && item.Clock + item.ID.getLength() <= clock_end) { v_track.addEvent((VsqEvent)item.clone(), item.InternalID); } } // 最後のRを手動で追加.これは自動化できない if (next_rest_clock != -1) { VsqEvent item = (VsqEvent)ve_next.clone(); item.ID.LyricHandle.L0.Phrase = "R"; item.Clock = next_rest_clock; item.ID.setLength(clock_end - next_rest_clock); v_track.addEvent(item); } // 0~選択範囲の開始位置までを削除する v.removePart(0, clock_start); // vsq -> ustに変換 // キーがustのIndex, 値がInternalID TreeMap <int, int> map = new TreeMap <int, int>(); UstFile u = new UstFile(v, 1, map); u.write(Path.Combine(PortUtil.getApplicationStartupPath(), "u.ust")); // PREV, NEXTのIndex値を設定する if (ve_prev != null || prev_is_rest) { u.getTrack(0).getEvent(0).Index = UstFile.PREV_INDEX; } if (ve_next != null) { u.getTrack(0).getEvent(u.getTrack(0).getEventCount() - 1).Index = UstFile.NEXT_INDEX; } // ustファイルに出力 UstFileWriteOptions option = new UstFileWriteOptions(); option.settingCacheDir = false; option.settingOutFile = false; option.settingProjectName = false; option.settingTempo = true; option.settingTool1 = true; option.settingTool2 = true; option.settingTracks = false; option.settingVoiceDir = true; option.trackEnd = false; string temp = Path.GetTempFileName(); u.write(temp, option); StringBuilder before = new StringBuilder(); using (StreamReader sr = new StreamReader(temp, System.Text.Encoding.GetEncoding("Shift_JIS"))) { string line = ""; while ((line = sr.ReadLine()) != null) { before.AppendLine(line); } } String md5_before = PortUtil.getMD5FromString(before.ToString()); // プラグインの実行ファイルを起動 Utau_Plugin_Invoker dialog = new Utau_Plugin_Invoker(exe_path, temp); dialog.ShowDialog(); StringBuilder after = new StringBuilder(); using (StreamReader sr = new StreamReader(temp, System.Text.Encoding.GetEncoding("Shift_JIS"))) { string line = ""; while ((line = sr.ReadLine()) != null) { after.AppendLine(line); } } String md5_after = PortUtil.getMD5FromString(after.ToString()); if (md5_before == md5_after) { // 編集されなかったようだ return(ScriptReturnStatus.NOT_EDITED); } // プラグインの実行結果をustオブジェクトにロード UstFile r = new UstFile(temp); if (r.getTrackCount() < 1) { return(ScriptReturnStatus.ERROR); } // 変更のなかったものについてはプラグインは記録してこないので, // 最初の値を代入するようにする UstTrack utrack_src = u.getTrack(0); UstTrack utrack_dst = r.getTrack(0); for (int i = 0; i < utrack_dst.getEventCount(); i++) { UstEvent ue_dst = utrack_dst.getEvent(i); int index = ue_dst.Index; UstEvent ue_src = utrack_src.findEventFromIndex(index); if (ue_src == null) { continue; } if (!ue_dst.isEnvelopeSpecified() && ue_src.isEnvelopeSpecified()) { ue_dst.setEnvelope(ue_src.getEnvelope()); } if (!ue_dst.isIntensitySpecified() && ue_src.isIntensitySpecified()) { ue_dst.setIntensity(ue_src.getIntensity()); } if (!ue_dst.isLengthSpecified() && ue_src.isLengthSpecified()) { ue_dst.setLength(ue_src.getLength()); } if (!ue_dst.isLyricSpecified() && ue_src.isLyricSpecified()) { ue_dst.setLyric(ue_src.getLyric()); } if (!ue_dst.isModurationSpecified() && ue_src.isModurationSpecified()) { ue_dst.setModuration(ue_src.getModuration()); } if (!ue_dst.isNoteSpecified() && ue_src.isNoteSpecified()) { ue_dst.setNote(ue_src.getNote()); } if (!ue_dst.isPBTypeSpecified() && ue_src.isPBTypeSpecified()) { ue_dst.setPBType(ue_src.getPBType()); } if (!ue_dst.isPitchesSpecified() && ue_src.isPitchesSpecified()) { ue_dst.setPitches(ue_src.getPitches()); } if (!ue_dst.isPortamentoSpecified() && ue_src.isPortamentoSpecified()) { ue_dst.setPortamento(ue_src.getPortamento()); } if (!ue_dst.isPreUtteranceSpecified() && ue_src.isPreUtteranceSpecified()) { ue_dst.setPreUtterance(ue_src.getPreUtterance()); } if (!ue_dst.isStartPointSpecified() && ue_src.isStartPointSpecified()) { ue_dst.setStartPoint(ue_src.getStartPoint()); } if (!ue_dst.isTempoSpecified() && ue_src.isTempoSpecified()) { ue_dst.setTempo(ue_src.getTempo()); } if (!ue_dst.isVibratoSpecified() && ue_src.isVibratoSpecified()) { ue_dst.setVibrato(ue_src.getVibrato()); } if (!ue_dst.isVoiceOverlapSpecified() && ue_src.isVoiceOverlapSpecified()) { ue_dst.setVoiceOverlap(ue_src.getVoiceOverlap()); } } // PREVとNEXT含めて,clock_startからclock_endまでプラグインに渡したけれど, // それが伸びて帰ってきたか縮んで帰ってきたか. int ret_length = 0; UstTrack r_track = r.getTrack(0); int size = r_track.getEventCount(); for (int i = 0; i < size; i++) { UstEvent ue = r_track.getEvent(i); // 戻りのustには,変更があったものしか記録されていない int ue_length = ue.getLength(); if (!ue.isLengthSpecified() && map.ContainsKey(ue.Index)) { int internal_id = map[ue.Index]; VsqEvent found_item = vsq_track.findEventFromID(internal_id); if (found_item != null) { ue_length = found_item.ID.getLength(); } } // PREV, ENDの場合は長さに加えない if (ue.Index != UstFile.NEXT_INDEX && ue.Index != UstFile.PREV_INDEX) { ret_length += ue_length; } } // 伸び縮みがあった場合 // 伸ばしたり縮めたりするよ int delta = ret_length - (sel_end - sel_start); if (delta > 0) { // のびた vsq.insertBlank(selected, sel_end, delta); } else if (delta < 0) { // 縮んだ vsq.removePart(selected, sel_end + delta, sel_end); } // r_trackの内容をvsq_trackに転写 size = r_track.getEventCount(); int c = clock_start; for (int i = 0; i < size; i++) { UstEvent ue = r_track.getEvent(i); if (ue.Index == UstFile.NEXT_INDEX || ue.Index == UstFile.PREV_INDEX) { // PREVとNEXTは単に無視する continue; } int ue_length = ue.getLength(); if (map.containsKey(ue.Index)) { // 既存の音符の編集 VsqEvent target = vsq_track.findEventFromID(map[ue.Index]); if (target == null) { // そんなばかな・・・ continue; } if (!ue.isLengthSpecified()) { ue_length = target.ID.getLength(); } if (target.UstEvent == null) { target.UstEvent = (UstEvent)ue.clone(); } // utau固有のパラメータを転写 // pitchは後でやるので無視していい // テンポもあとでやるので無視していい if (ue.isEnvelopeSpecified()) { target.UstEvent.setEnvelope(ue.getEnvelope()); } if (ue.isModurationSpecified()) { target.UstEvent.setModuration(ue.getModuration()); } if (ue.isPBTypeSpecified()) { target.UstEvent.setPBType(ue.getPBType()); } if (ue.isPortamentoSpecified()) { target.UstEvent.setPortamento(ue.getPortamento()); } if (ue.isPreUtteranceSpecified()) { target.UstEvent.setPreUtterance(ue.getPreUtterance()); } if (ue.isStartPointSpecified()) { target.UstEvent.setStartPoint(ue.getStartPoint()); } if (ue.isVibratoSpecified()) { target.UstEvent.setVibrato(ue.getVibrato()); } if (ue.isVoiceOverlapSpecified()) { target.UstEvent.setVoiceOverlap(ue.getVoiceOverlap()); } // vocaloid, utauで同じ意味のパラメータを転写 if (ue.isIntensitySpecified()) { target.UstEvent.setIntensity(ue.getIntensity()); target.ID.Dynamics = ue.getIntensity(); } if (ue.isLengthSpecified()) { target.UstEvent.setLength(ue.getLength()); target.ID.setLength(ue.getLength()); } if (ue.isLyricSpecified()) { target.UstEvent.setLyric(ue.getLyric()); target.ID.LyricHandle.L0.Phrase = ue.getLyric(); } if (ue.isNoteSpecified()) { target.UstEvent.setNote(ue.getNote()); target.ID.Note = ue.getNote(); } } else { // マップに入っていないので,新しい音符の追加だと思う if (ue.getLyric() == "R") { // 休符.なにもしない } else { VsqEvent newe = new VsqEvent(); newe.Clock = c; newe.UstEvent = (UstEvent)ue.clone(); newe.ID = new VsqID(); AppManager.editorConfig.applyDefaultSingerStyle(newe.ID); if (ue.isIntensitySpecified()) { newe.ID.Dynamics = ue.getIntensity(); } newe.ID.LyricHandle = new LyricHandle("あ", "a"); if (ue.isLyricSpecified()) { newe.ID.LyricHandle.L0.Phrase = ue.getLyric(); } newe.ID.Note = ue.getNote(); newe.ID.setLength(ue.getLength()); newe.ID.type = VsqIDType.Anote; // internal id はaddEventメソッドで自動で割り振られる vsq_track.addEvent(newe); } } // テンポの追加がないかチェック if (ue.isTempoSpecified()) { insertTempoInto(vsq, c, ue.getTempo()); } c += ue_length; } // ピッチを転写 // pitのデータがほしいので,PREV, NEXTを削除して,VsqFileにコンバートする UstFile uf = (UstFile)r.clone(); // prev, nextを削除 UstTrack uf_track = uf.getTrack(0); for (int i = 0; i < uf_track.getEventCount();) { UstEvent ue = uf_track.getEvent(i); if (ue.Index == UstFile.NEXT_INDEX || ue.Index == UstFile.PREV_INDEX) { uf_track.removeEventAt(i); } else { i++; } } uf.updateTempoInfo(); // VsqFileにコンバート VsqFile uf_vsq = new VsqFile(uf); // uf_vsqの最初のトラックの0からret_lengthクロックまでが, // vsq_trackのsel_startからsel_start+ret_lengthクロックまでに対応する. // まずPBSをコピーする CurveType[] type = new CurveType[] { CurveType.PBS, CurveType.PIT }; foreach (CurveType ct in type) { // コピー元を取得 VsqBPList src = uf_vsq.Track[1].getCurve(ct.getName()); if (src != null) { // コピー先を取得 VsqBPList dst = vsq_track.getCurve(ct.getName()); if (dst == null) { // コピー先がnullだった場合は作成 dst = new VsqBPList(ct.getName(), ct.getDefault(), ct.getMinimum(), ct.getMaximum()); vsq_track.setCurve(ct.getName(), dst); } // あとで復元するので,最終位置での値を保存しておく int value_at_end = dst.getValue(sel_start + ret_length); // 復元するかどうか.最終位置にそもそもデータ点があれば復帰の必要がないので. bool do_revert = (dst.findIndexFromClock(sel_start + ret_length) < 0); // [sel_start, sel_start + ret_length)の範囲の値を削除しておく size = dst.size(); for (int i = size - 1; i >= 0; i--) { int cl = dst.getKeyClock(i); if (sel_start <= cl && cl < sel_start + ret_length) { dst.removeElementAt(i); } } // コピーを実行 size = src.size(); for (int i = 0; i < size; i++) { int cl = src.getKeyClock(i); if (ret_length <= cl) { break; } int value = src.getElementA(i); dst.add(cl + sel_start, value); } // コピー後,最終位置での値が元と異なる場合,元に戻すようにする if (do_revert && dst.getValue(sel_start + ret_length) != value_at_end) { dst.add(sel_start + ret_length, value_at_end); } } } return(ScriptReturnStatus.EDITED); }
protected abstract EventQueueSequence generateMidiEvent( VsqFileEx vsq, int track, int clock_start, int clock_end );
public static ScriptReturnStatus Edit( VsqFileEx vsq ){ if( AppManager.getSelectedEventCount() <= 0 ){ return ScriptReturnStatus.NOT_EDITED; } string pluginTxtPath = s_plugin_txt_path; if( pluginTxtPath == "" ){ AppManager.showMessageBox( "pluginTxtPath=" + pluginTxtPath ); return ScriptReturnStatus.ERROR; } if( !System.IO.File.Exists( pluginTxtPath ) ){ AppManager.showMessageBox( "'" + pluginTxtPath + "' does not exists" ); return ScriptReturnStatus.ERROR; } System.Text.Encoding shift_jis = System.Text.Encoding.GetEncoding( "Shift_JIS" ); string name = ""; string exe_path = ""; using( StreamReader sr = new StreamReader( pluginTxtPath, shift_jis ) ){ string line = ""; while( (line = sr.ReadLine()) != null ){ string[] spl = line.Split( new char[]{ '=' }, StringSplitOptions.RemoveEmptyEntries ); if( line.StartsWith( "name=" ) ){ name = spl[1]; }else if( line.StartsWith( "execute=" ) ){ exe_path = Path.Combine( Path.GetDirectoryName( pluginTxtPath ), spl[1] ); } } } if( exe_path == "" ){ return ScriptReturnStatus.ERROR; } if( !System.IO.File.Exists( exe_path ) ){ AppManager.showMessageBox( "'" + exe_path + "' does not exists" ); return ScriptReturnStatus.ERROR; } // ustを用意 ------------------------------------------------------------------------ // 方針は,一度VsqFileに音符を格納->UstFile#.ctor( VsqFile )を使って一括変換 // メイン画面で選択されているアイテムを列挙 List<VsqEvent> items = new List<VsqEvent>(); for( Iterator itr = AppManager.getSelectedEventIterator(); itr.hasNext(); ){ SelectedEventEntry item_itr = (SelectedEventEntry)itr.next(); if( item_itr.original.ID.type == VsqIDType.Anote ){ items.Add( (VsqEvent)item_itr.original.clone() ); } } items.Sort(); // R用音符のテンプレート VsqEvent template = new VsqEvent(); template.ID.type = VsqIDType.Anote; template.ID.LyricHandle = new LyricHandle( "R", "" ); int count = items.Count; // アイテムが2個以上の場合は、間にRを挿入する必要があるかどうか判定 if( count > 1 ){ List<VsqEvent> add = new List<VsqEvent>(); // 追加するR VsqEvent last_event = items[0]; for( int i = 1; i < count; i++ ){ VsqEvent item = items[i]; if( last_event.Clock + last_event.ID.Length < item.Clock ){ VsqEvent add_temp = (VsqEvent)template.clone(); add_temp.Clock = last_event.Clock + last_event.ID.Length; add_temp.ID.Length = item.Clock - add_temp.Clock; add.Add( add_temp ); } last_event = item; } foreach( VsqEvent v in add ){ items.Add( v ); } items.Sort(); } // ヘッダ int TEMPO = 120; // 選択アイテムの直前直後に未選択アイテムがあるかどうかを判定 int clock_begin = items[0].Clock; int clock_end = items[items.Count - 1].Clock; VsqTrack vsq_track = vsq.Track.get( AppManager.getSelected() ); VsqEvent tlast_event = null; VsqEvent prev = null; VsqEvent next = null; // VsqFile -> UstFileのコンバート VsqFile conv = new VsqFile( "Miku", 2, 4, 4, (int)(6e7 / TEMPO) ); VsqTrack conv_track = conv.Track.get( 1 ); for( Iterator itr = vsq_track.getNoteEventIterator(); itr.hasNext(); ){ VsqEvent item_itr = (VsqEvent)itr.next(); if( item_itr.Clock == clock_begin ){ if( tlast_event != null ){ // アイテムあり if( tlast_event.Clock + tlast_event.ID.Length == clock_begin ){ // ゲートタイム差0で接続 prev = (VsqEvent)tlast_event.clone(); }else{ // 時間差アリで接続 prev = (VsqEvent)template.clone(); prev.Clock = tlast_event.Clock + tlast_event.ID.Length; prev.ID.Length = clock_begin - (tlast_event.Clock + tlast_event.ID.Length); } } } tlast_event = item_itr; if( item_itr.Clock == clock_end ){ if( itr.hasNext() ){ VsqEvent foo = (VsqEvent)itr.next(); int clock_end_end = clock_end + items[items.Count - 1].ID.Length; if( foo.Clock == clock_end_end ){ // ゲートタイム差0で接続 next = (VsqEvent)foo.clone(); }else{ // 時間差アリで接続 next = (VsqEvent)template.clone(); next.Clock = clock_end_end; next.ID.Length = foo.Clock - clock_end_end; } } break; } } // [#PREV]を追加 if( prev != null ){ prev.Clock -= clock_begin; conv_track.addEvent( prev ); } // ゲートタイムを計算しながら追加 count = items.Count; for( int i = 0; i < count; i++ ){ VsqEvent itemi = items[i]; itemi.Clock -= clock_begin; conv_track.addEvent( itemi ); } // [#NEXT]を追加 if( next != null ){ next.Clock -= clock_begin; conv_track.addEvent( next ); } // PIT, PBSを追加 copyCurve( vsq_track.getCurve( "pit" ), conv_track.getCurve( "pit" ), clock_begin ); copyCurve( vsq_track.getCurve( "pbs" ), conv_track.getCurve( "pbs" ), clock_begin ); string temp = Path.GetTempFileName(); UstFile tust = new UstFile( conv, 1 ); if( prev != null ){ tust.getTrack( 0 ).getEvent( 0 ).Index = int.MinValue; } if( next != null ){ tust.getTrack( 0 ).getEvent( tust.getTrack( 0 ).getEventCount() - 1 ).Index = int.MaxValue; } tust.write( temp ); // 起動 ----------------------------------------------------------------------------- StartPluginArgs arg = new StartPluginArgs(); arg.exePath = exe_path; arg.tmpFile = temp; System.Threading.Thread t = new System.Threading.Thread( new System.Threading.ParameterizedThreadStart( runPlugin ) ); s_finished = false; t.Start( arg ); while( !s_finished ){ Application.DoEvents(); } // 結果を反映 ----------------------------------------------------------------------- UstFile ust = null; try{ ust = new UstFile( temp ); }catch( Exception ex ){ AppManager.showMessageBox( "invalid ust file; ex=" + ex ); return ScriptReturnStatus.ERROR; } int track_count = ust.getTrackCount(); for( int i = 0; i < track_count; i++ ){ UstTrack track = ust.getTrack( i ); int event_count = track.getEventCount(); for( int j = 0; j < event_count; j++ ){ UstEvent itemj = track.getEvent( j ); if( itemj.Index == int.MinValue ){ AppManager.showMessageBox( "[#PREV]" ); }else if( itemj.Index == int.MaxValue ){ AppManager.showMessageBox( "[#NEXT]" ); }else{ AppManager.showMessageBox( itemj.Index + "" ); } } } try{ System.IO.File.Delete( temp ); }catch( Exception ex ){ } return ScriptReturnStatus.ERROR; }
public static ScriptReturnStatus Edit( VsqFileEx vsq ) { // 選択状態のアイテムがなければ戻る if ( AppManager.itemSelection.getEventCount() <= 0 ) { return ScriptReturnStatus.NOT_EDITED; } // 現在のトラック int selected = AppManager.getSelected(); VsqTrack vsq_track = vsq.Track.get( selected ); vsq_track.sortEvent(); // プラグイン情報の定義ファイル(plugin.txt)があるかどうかチェック string pluginTxtPath = s_plugin_txt_path; if ( pluginTxtPath == "" ) { AppManager.showMessageBox( "pluginTxtPath=" + pluginTxtPath ); return ScriptReturnStatus.ERROR; } if ( !System.IO.File.Exists( pluginTxtPath ) ) { AppManager.showMessageBox( "'" + pluginTxtPath + "' does not exists" ); return ScriptReturnStatus.ERROR; } // plugin.txtがあれば,プラグインの実行ファイルのパスを取得する System.Text.Encoding shift_jis = System.Text.Encoding.GetEncoding( "Shift_JIS" ); string name = ""; string exe_path = ""; using ( StreamReader sr = new StreamReader( pluginTxtPath, shift_jis ) ) { string line = ""; while ( (line = sr.ReadLine()) != null ) { string[] spl = line.Split( new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries ); if ( line.StartsWith( "name=" ) ) { name = spl[1]; } else if ( line.StartsWith( "execute=" ) ) { exe_path = Path.Combine( Path.GetDirectoryName( pluginTxtPath ), spl[1] ); } } } if ( exe_path == "" ) { return ScriptReturnStatus.ERROR; } if ( !System.IO.File.Exists( exe_path ) ) { AppManager.showMessageBox( "'" + exe_path + "' does not exists" ); return ScriptReturnStatus.ERROR; } // 選択状態のアイテムの最初と最後がどこか調べる // clock_start, clock_endは,最終的にはPREV, NEXTを含んだ範囲を表すことになる // sel_start, sel_endはPREV, NEXTを含まない選択範囲を表す int id_start = -1; int clock_start = int.MaxValue; int id_end = -1; int clock_end = int.MinValue; int sel_start = 0; int sel_end = 0; for ( Iterator<SelectedEventEntry> itr = AppManager.itemSelection.getEventIterator(); itr.hasNext(); ) { SelectedEventEntry item = itr.next(); if ( item.original.ID.type != VsqIDType.Anote ) { continue; } int clock = item.original.Clock; if ( clock < clock_start ) { id_start = item.original.InternalID; clock_start = clock; sel_start = clock; } clock += item.original.ID.getLength(); if ( clock_end < clock ) { id_end = item.original.InternalID; clock_end = clock; sel_end = clock; } } // 選択範囲の前後の音符を探す VsqEvent ve_prev = null; VsqEvent ve_next = null; VsqEvent l = null; for ( Iterator<VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext(); ) { VsqEvent item = itr.next(); if ( item.InternalID == id_start ) { if ( l != null ) { ve_prev = l; } } if ( l != null ) { if ( l.InternalID == id_end ) { ve_next = item; } } l = item; if ( ve_prev != null && ve_next != null ) { break; } } int next_rest_clock = -1; bool prev_is_rest = false; if ( ve_prev != null ) { // 直前の音符がある場合 if ( ve_prev.Clock + ve_prev.ID.getLength() == clock_start ) { // 接続している clock_start = ve_prev.Clock; } else { // 接続していない int new_clock_start = ve_prev.Clock + ve_prev.ID.getLength(); clock_start = new_clock_start; } } else { // 無い場合 if ( vsq.getPreMeasureClocks() < clock_start ) { prev_is_rest = true; } int new_clock_start = vsq.getPreMeasureClocks(); clock_start = new_clock_start; } if ( ve_next != null ) { // 直後の音符がある場合 if ( ve_next.Clock == clock_end ) { // 接続している clock_end = ve_next.Clock + ve_next.ID.getLength(); } else { // 接続していない next_rest_clock = clock_end; clock_end = ve_next.Clock; } } // 作業用のVSQに,選択範囲のアイテムを格納 VsqFileEx v = (VsqFileEx)vsq.clone();// new VsqFile( "Miku", 1, 4, 4, 500000 ); // 選択トラックだけ残して他を削る for ( int i = 1; i < selected; i++ ) { v.Track.removeElementAt( 1 ); } for ( int i = selected + 1; i < v.Track.size(); i++ ) { v.Track.removeElementAt( selected + 1 ); } // 選択トラックの音符を全消去する VsqTrack v_track = v.Track.get( 1 ); v_track.MetaText.getEventList().clear(); for ( Iterator<VsqEvent> itr = vsq_track.getNoteEventIterator(); itr.hasNext(); ) { VsqEvent item = itr.next(); if ( clock_start <= item.Clock && item.Clock + item.ID.getLength() <= clock_end ) { v_track.addEvent( (VsqEvent)item.clone(), item.InternalID ); } } // 最後のRを手動で追加.これは自動化できない if ( next_rest_clock != -1 ) { VsqEvent item = (VsqEvent)ve_next.clone(); item.ID.LyricHandle.L0.Phrase = "R"; item.Clock = next_rest_clock; item.ID.setLength( clock_end - next_rest_clock ); v_track.addEvent( item ); } // 0~選択範囲の開始位置までを削除する v.removePart( 0, clock_start ); // vsq -> ustに変換 // キーがustのIndex, 値がInternalID TreeMap<int, int> map = new TreeMap<int, int>(); UstFile u = new UstFile( v, 1, map ); u.write( Path.Combine( PortUtil.getApplicationStartupPath(), "u.ust" ) ); // PREV, NEXTのIndex値を設定する if ( ve_prev != null || prev_is_rest ) { u.getTrack( 0 ).getEvent( 0 ).Index = UstFile.PREV_INDEX; } if ( ve_next != null ) { u.getTrack( 0 ).getEvent( u.getTrack( 0 ).getEventCount() - 1 ).Index = UstFile.NEXT_INDEX; } // ustファイルに出力 UstFileWriteOptions option = new UstFileWriteOptions(); option.settingCacheDir = false; option.settingOutFile = false; option.settingProjectName = false; option.settingTempo = true; option.settingTool1 = true; option.settingTool2 = true; option.settingTracks = false; option.settingVoiceDir = true; option.trackEnd = false; string temp = Path.GetTempFileName(); u.write( temp, option ); StringBuilder before = new StringBuilder(); using ( StreamReader sr = new StreamReader( temp, System.Text.Encoding.GetEncoding( "Shift_JIS" ) ) ) { string line = ""; while ( (line = sr.ReadLine()) != null ) { before.AppendLine( line ); } } String md5_before = PortUtil.getMD5FromString( before.ToString() ); // プラグインの実行ファイルを起動 Utau_Plugin_Invoker dialog = new Utau_Plugin_Invoker( exe_path, temp ); dialog.ShowDialog(); StringBuilder after = new StringBuilder(); using ( StreamReader sr = new StreamReader( temp, System.Text.Encoding.GetEncoding( "Shift_JIS" ) ) ) { string line = ""; while ( (line = sr.ReadLine()) != null ) { after.AppendLine( line ); } } String md5_after = PortUtil.getMD5FromString( after.ToString() ); if ( md5_before == md5_after ) { // 編集されなかったようだ return ScriptReturnStatus.NOT_EDITED; } // プラグインの実行結果をustオブジェクトにロード UstFile r = new UstFile( temp ); if ( r.getTrackCount() < 1 ) { return ScriptReturnStatus.ERROR; } // 変更のなかったものについてはプラグインは記録してこないので, // 最初の値を代入するようにする UstTrack utrack_src = u.getTrack( 0 ); UstTrack utrack_dst = r.getTrack( 0 ); for ( int i = 0; i < utrack_dst.getEventCount(); i++ ) { UstEvent ue_dst = utrack_dst.getEvent( i ); int index = ue_dst.Index; UstEvent ue_src = utrack_src.findEventFromIndex( index ); if ( ue_src == null ) { continue; } if ( !ue_dst.isEnvelopeSpecified() && ue_src.isEnvelopeSpecified() ) { ue_dst.setEnvelope( ue_src.getEnvelope() ); } if ( !ue_dst.isIntensitySpecified() && ue_src.isIntensitySpecified() ) { ue_dst.setIntensity( ue_src.getIntensity() ); } if ( !ue_dst.isLengthSpecified() && ue_src.isLengthSpecified() ) { ue_dst.setLength( ue_src.getLength() ); } if ( !ue_dst.isLyricSpecified() && ue_src.isLyricSpecified() ) { ue_dst.setLyric( ue_src.getLyric() ); } if ( !ue_dst.isModurationSpecified() && ue_src.isModurationSpecified() ) { ue_dst.setModuration( ue_src.getModuration() ); } if ( !ue_dst.isNoteSpecified() && ue_src.isNoteSpecified() ) { ue_dst.setNote( ue_src.getNote() ); } if ( !ue_dst.isPBTypeSpecified() && ue_src.isPBTypeSpecified() ) { ue_dst.setPBType( ue_src.getPBType() ); } if ( !ue_dst.isPitchesSpecified() && ue_src.isPitchesSpecified() ) { ue_dst.setPitches( ue_src.getPitches() ); } if ( !ue_dst.isPortamentoSpecified() && ue_src.isPortamentoSpecified() ) { ue_dst.setPortamento( ue_src.getPortamento() ); } if ( !ue_dst.isPreUtteranceSpecified() && ue_src.isPreUtteranceSpecified() ) { ue_dst.setPreUtterance( ue_src.getPreUtterance() ); } if ( !ue_dst.isStartPointSpecified() && ue_src.isStartPointSpecified() ) { ue_dst.setStartPoint( ue_src.getStartPoint() ); } if ( !ue_dst.isTempoSpecified() && ue_src.isTempoSpecified() ) { ue_dst.setTempo( ue_src.getTempo() ); } if ( !ue_dst.isVibratoSpecified() && ue_src.isVibratoSpecified() ) { ue_dst.setVibrato( ue_src.getVibrato() ); } if ( !ue_dst.isVoiceOverlapSpecified() && ue_src.isVoiceOverlapSpecified() ) { ue_dst.setVoiceOverlap( ue_src.getVoiceOverlap() ); } } // PREVとNEXT含めて,clock_startからclock_endまでプラグインに渡したけれど, // それが伸びて帰ってきたか縮んで帰ってきたか. int ret_length = 0; UstTrack r_track = r.getTrack( 0 ); int size = r_track.getEventCount(); for ( int i = 0; i < size; i++ ) { UstEvent ue = r_track.getEvent( i ); // 戻りのustには,変更があったものしか記録されていない int ue_length = ue.getLength(); if ( !ue.isLengthSpecified() && map.ContainsKey( ue.Index ) ) { int internal_id = map[ue.Index]; VsqEvent found_item = vsq_track.findEventFromID( internal_id ); if ( found_item != null ) { ue_length = found_item.ID.getLength(); } } // PREV, ENDの場合は長さに加えない if ( ue.Index != UstFile.NEXT_INDEX && ue.Index != UstFile.PREV_INDEX ) { ret_length += ue_length; } } // 伸び縮みがあった場合 // 伸ばしたり縮めたりするよ int delta = ret_length - (sel_end - sel_start); if ( delta > 0 ) { // のびた vsq.insertBlank( selected, sel_end, delta ); } else if ( delta < 0 ) { // 縮んだ vsq.removePart( selected, sel_end + delta, sel_end ); } // r_trackの内容をvsq_trackに転写 size = r_track.getEventCount(); int c = clock_start; for ( int i = 0; i < size; i++ ) { UstEvent ue = r_track.getEvent( i ); if ( ue.Index == UstFile.NEXT_INDEX || ue.Index == UstFile.PREV_INDEX ) { // PREVとNEXTは単に無視する continue; } int ue_length = ue.getLength(); if ( map.containsKey( ue.Index ) ) { // 既存の音符の編集 VsqEvent target = vsq_track.findEventFromID( map[ue.Index] ); if ( target == null ) { // そんなばかな・・・ continue; } if ( !ue.isLengthSpecified() ) { ue_length = target.ID.getLength(); } if ( target.UstEvent == null ) { target.UstEvent = (UstEvent)ue.clone(); } // utau固有のパラメータを転写 // pitchは後でやるので無視していい // テンポもあとでやるので無視していい if ( ue.isEnvelopeSpecified() ) { target.UstEvent.setEnvelope( ue.getEnvelope() ); } if ( ue.isModurationSpecified() ) { target.UstEvent.setModuration( ue.getModuration() ); } if ( ue.isPBTypeSpecified() ) { target.UstEvent.setPBType( ue.getPBType() ); } if ( ue.isPortamentoSpecified() ) { target.UstEvent.setPortamento( ue.getPortamento() ); } if ( ue.isPreUtteranceSpecified() ) { target.UstEvent.setPreUtterance( ue.getPreUtterance() ); } if ( ue.isStartPointSpecified() ) { target.UstEvent.setStartPoint( ue.getStartPoint() ); } if ( ue.isVibratoSpecified() ) { target.UstEvent.setVibrato( ue.getVibrato() ); } if ( ue.isVoiceOverlapSpecified() ) { target.UstEvent.setVoiceOverlap( ue.getVoiceOverlap() ); } // vocaloid, utauで同じ意味のパラメータを転写 if ( ue.isIntensitySpecified() ) { target.UstEvent.setIntensity( ue.getIntensity() ); target.ID.Dynamics = ue.getIntensity(); } if ( ue.isLengthSpecified() ) { target.UstEvent.setLength( ue.getLength() ); target.ID.setLength( ue.getLength() ); } if ( ue.isLyricSpecified() ) { target.UstEvent.setLyric( ue.getLyric() ); target.ID.LyricHandle.L0.Phrase = ue.getLyric(); } if ( ue.isNoteSpecified() ) { target.UstEvent.setNote( ue.getNote() ); target.ID.Note = ue.getNote(); } } else { // マップに入っていないので,新しい音符の追加だと思う if ( ue.getLyric() == "R" ) { // 休符.なにもしない } else { VsqEvent newe = new VsqEvent(); newe.Clock = c; newe.UstEvent = (UstEvent)ue.clone(); newe.ID = new VsqID(); AppManager.editorConfig.applyDefaultSingerStyle( newe.ID ); if ( ue.isIntensitySpecified() ) { newe.ID.Dynamics = ue.getIntensity(); } newe.ID.LyricHandle = new LyricHandle( "あ", "a" ); if ( ue.isLyricSpecified() ) { newe.ID.LyricHandle.L0.Phrase = ue.getLyric(); } newe.ID.Note = ue.getNote(); newe.ID.setLength( ue.getLength() ); newe.ID.type = VsqIDType.Anote; // internal id はaddEventメソッドで自動で割り振られる vsq_track.addEvent( newe ); } } // テンポの追加がないかチェック if ( ue.isTempoSpecified() ) { insertTempoInto( vsq, c, ue.getTempo() ); } c += ue_length; } // ピッチを転写 // pitのデータがほしいので,PREV, NEXTを削除して,VsqFileにコンバートする UstFile uf = (UstFile)r.clone(); // prev, nextを削除 UstTrack uf_track = uf.getTrack( 0 ); for ( int i = 0; i < uf_track.getEventCount(); ) { UstEvent ue = uf_track.getEvent( i ); if ( ue.Index == UstFile.NEXT_INDEX || ue.Index == UstFile.PREV_INDEX ) { uf_track.removeEventAt( i ); } else { i++; } } uf.updateTempoInfo(); // VsqFileにコンバート VsqFile uf_vsq = new VsqFile( uf ); // uf_vsqの最初のトラックの0からret_lengthクロックまでが, // vsq_trackのsel_startからsel_start+ret_lengthクロックまでに対応する. // まずPBSをコピーする CurveType[] type = new CurveType[] { CurveType.PBS, CurveType.PIT }; foreach ( CurveType ct in type ) { // コピー元を取得 VsqBPList src = uf_vsq.Track[1].getCurve( ct.getName() ); if ( src != null ) { // コピー先を取得 VsqBPList dst = vsq_track.getCurve( ct.getName() ); if ( dst == null ) { // コピー先がnullだった場合は作成 dst = new VsqBPList( ct.getName(), ct.getDefault(), ct.getMinimum(), ct.getMaximum() ); vsq_track.setCurve( ct.getName(), dst ); } // あとで復元するので,最終位置での値を保存しておく int value_at_end = dst.getValue( sel_start + ret_length ); // 復元するかどうか.最終位置にそもそもデータ点があれば復帰の必要がないので. bool do_revert = (dst.findIndexFromClock( sel_start + ret_length ) < 0); // [sel_start, sel_start + ret_length)の範囲の値を削除しておく size = dst.size(); for ( int i = size - 1; i >= 0; i-- ) { int cl = dst.getKeyClock( i ); if ( sel_start <= cl && cl < sel_start + ret_length ) { dst.removeElementAt( i ); } } // コピーを実行 size = src.size(); for ( int i = 0; i < size; i++ ) { int cl = src.getKeyClock( i ); if ( ret_length <= cl ) { break; } int value = src.getElementA( i ); dst.add( cl + sel_start, value ); } // コピー後,最終位置での値が元と異なる場合,元に戻すようにする if ( do_revert && dst.getValue( sel_start + ret_length ) != value_at_end ) { dst.add( sel_start + ret_length, value_at_end ); } } } return ScriptReturnStatus.EDITED; }
/// <summary> /// 初期化メソッド /// </summary> /// <param name="parameter"></param> public void init( VsqFileEx vsq, int track, int start_clock, int end_clock, int sample_rate ) { getDriver().setSampleRate( sample_rate ); mTrack = track; mStartClock = start_clock; mEndClock = end_clock; mSampleRate = sample_rate; this.mVsq = (VsqFileEx)vsq.clone(); this.mVsq.updateTotalClocks(); if ( mEndClock < this.mVsq.TotalClocks ) { this.mVsq.removePart( mEndClock, this.mVsq.TotalClocks + 480 ); } double end_sec = mVsq.getSecFromClock( start_clock ); double start_sec = mVsq.getSecFromClock( end_clock ); double trim_sec = 0.0; // レンダリング結果から省かなければならない秒数。 if ( mStartClock < this.mVsq.getPreMeasureClocks() ) { trim_sec = this.mVsq.getSecFromClock( mStartClock ); } else { this.mVsq.removePart( mVsq.getPreMeasureClocks(), mStartClock ); trim_sec = this.mVsq.getSecFromClock( this.mVsq.getPreMeasureClocks() ); } this.mVsq.updateTotalClocks(); mTrimRemain = (int)(trim_sec * mSampleRate); //mTrimRemain = 0; #if DEBUG sout.println( "AeuqsToneWaveGenerator#init; mTrimRemain=" + mTrimRemain ); #endif }
/// <summary> /// 指定したVSQの指定した位置に,テンポの挿入を試みます. /// 既存のテンポがある場合,値が上書きされます /// </summary> /// <param name="vsq">挿入対象のVSQ</param> /// <param name="clock">挿入位置</param> /// <param name="tempo">楽譜表記上のテンポ.BPS</param> private static void insertTempoInto( VsqFileEx vsq, int clock, float t ) { // clockの位置にテンポ変更があるかどうか? int num_tempo = vsq.TempoTable.size(); int index = -1; for ( int j = 0; j < num_tempo; j++ ) { TempoTableEntry itemj = vsq.TempoTable[j]; if ( itemj.Clock == clock ) { index = j; break; } } int tempo = (int)(60e6 / t); if ( index >= 0 ) { // clock位置に既存のテンポ変更がある場合,テンポ値を変更 TempoTableEntry itemj = vsq.TempoTable[index]; itemj.Tempo = tempo; } else { // 既存のものはないので新規に追加 vsq.TempoTable.Add( new TempoTableEntry( clock, tempo, 0.0 ) ); } // テンポテーブルを更新 vsq.TempoTable.updateTempoInfo(); }
public void showPrefs(Form Parent, System.Drawing.Point location, bool showVBCfg) { try { if (mDialogPreference == null) { mDialogPreference = new Preference(); } mDialogPreference.setBaseFont(new Font(AppManager.editorConfig.BaseFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9)); mDialogPreference.setScreenFont(new Font(AppManager.editorConfig.ScreenFontName, java.awt.Font.PLAIN, AppManager.FONT_SIZE9)); mDialogPreference.setWheelOrder(AppManager.editorConfig.WheelOrder); mDialogPreference.setCursorFixed(AppManager.editorConfig.CursorFixed); mDialogPreference.setDefaultVibratoLength(AppManager.editorConfig.DefaultVibratoLength); mDialogPreference.setAutoVibratoThresholdLength(AppManager.editorConfig.AutoVibratoThresholdLength); mDialogPreference.setAutoVibratoType1(AppManager.editorConfig.AutoVibratoType1); mDialogPreference.setAutoVibratoType2(AppManager.editorConfig.AutoVibratoType2); mDialogPreference.setAutoVibratoTypeCustom(AppManager.editorConfig.AutoVibratoTypeCustom); mDialogPreference.setEnableAutoVibrato(AppManager.editorConfig.EnableAutoVibrato); mDialogPreference.setPreSendTime(AppManager.editorConfig.PreSendTime); mDialogPreference.setControlCurveResolution(AppManager.editorConfig.ControlCurveResolution); mDialogPreference.setDefaultSingerName(AppManager.editorConfig.DefaultSingerName); mDialogPreference.setScrollHorizontalOnWheel(AppManager.editorConfig.ScrollHorizontalOnWheel); mDialogPreference.setMaximumFrameRate(AppManager.editorConfig.MaximumFrameRate); mDialogPreference.setKeepLyricInputMode(AppManager.editorConfig.KeepLyricInputMode); mDialogPreference.setPxTrackHeight(AppManager.editorConfig.PxTrackHeight); mDialogPreference.setMouseHoverTime(AppManager.editorConfig.getMouseHoverTime()); mDialogPreference.setPlayPreviewWhenRightClick(AppManager.editorConfig.PlayPreviewWhenRightClick); mDialogPreference.setCurveSelectingQuantized(AppManager.editorConfig.CurveSelectingQuantized); mDialogPreference.setCurveVisibleAccent(AppManager.editorConfig.CurveVisibleAccent); mDialogPreference.setCurveVisibleBre(AppManager.editorConfig.CurveVisibleBreathiness); mDialogPreference.setCurveVisibleBri(AppManager.editorConfig.CurveVisibleBrightness); mDialogPreference.setCurveVisibleCle(AppManager.editorConfig.CurveVisibleClearness); mDialogPreference.setCurveVisibleDecay(AppManager.editorConfig.CurveVisibleDecay); mDialogPreference.setCurveVisibleDyn(AppManager.editorConfig.CurveVisibleDynamics); mDialogPreference.setCurveVisibleGen(AppManager.editorConfig.CurveVisibleGendorfactor); mDialogPreference.setCurveVisibleOpe(AppManager.editorConfig.CurveVisibleOpening); mDialogPreference.setCurveVisiblePit(AppManager.editorConfig.CurveVisiblePit); mDialogPreference.setCurveVisiblePbs(AppManager.editorConfig.CurveVisiblePbs); mDialogPreference.setCurveVisiblePor(AppManager.editorConfig.CurveVisiblePortamento); mDialogPreference.setCurveVisibleVel(AppManager.editorConfig.CurveVisibleVelocity); mDialogPreference.setCurveVisibleVibratoDepth(AppManager.editorConfig.CurveVisibleVibratoDepth); mDialogPreference.setCurveVisibleVibratoRate(AppManager.editorConfig.CurveVisibleVibratoRate); mDialogPreference.setCurveVisibleFx2Depth(AppManager.editorConfig.CurveVisibleFx2Depth); mDialogPreference.setCurveVisibleHarmonics(AppManager.editorConfig.CurveVisibleHarmonics); mDialogPreference.setCurveVisibleReso1(AppManager.editorConfig.CurveVisibleReso1); mDialogPreference.setCurveVisibleReso2(AppManager.editorConfig.CurveVisibleReso2); mDialogPreference.setCurveVisibleReso3(AppManager.editorConfig.CurveVisibleReso3); mDialogPreference.setCurveVisibleReso4(AppManager.editorConfig.CurveVisibleReso4); mDialogPreference.setCurveVisibleEnvelope(AppManager.editorConfig.CurveVisibleEnvelope); #if ENABLE_MIDI mDialogPreference.setMidiInPort(AppManager.editorConfig.MidiInPort.PortNumber); #endif #if ENABLE_MTC m_preference_dlg.setMtcMidiInPort(AppManager.editorConfig.MidiInPortMtc.PortNumber); #endif Vector <String> resamplers = new Vector <String>(); Vector <Boolean> with_wine = new Vector <Boolean>(); int size = AppManager.editorConfig.getResamplerCount(); for (int i = 0; i < size; i++) { resamplers.add(AppManager.editorConfig.getResamplerAt(i)); with_wine.add(AppManager.editorConfig.isResamplerWithWineAt(i)); } mDialogPreference.setResamplersConfig(resamplers, with_wine); mDialogPreference.setPathWavtool(AppManager.editorConfig.PathWavtool); mDialogPreference.setWavtoolWithWine(AppManager.editorConfig.WavtoolWithWine); mDialogPreference.setUtausingers(AppManager.editorConfig.UtauSingers); mDialogPreference.setSelfDeRomantization(AppManager.editorConfig.SelfDeRomanization); mDialogPreference.setAutoBackupIntervalMinutes(AppManager.editorConfig.AutoBackupIntervalMinutes); mDialogPreference.setUseSpaceKeyAsMiddleButtonModifier(AppManager.editorConfig.UseSpaceKeyAsMiddleButtonModifier); mDialogPreference.setPathAquesTone(AppManager.editorConfig.PathAquesTone); mDialogPreference.setPathAquesTone2(AppManager.editorConfig.PathAquesTone2); mDialogPreference.setUseProjectCache(AppManager.editorConfig.UseProjectCache); mDialogPreference.setAquesToneRequired(!AppManager.editorConfig.DoNotUseAquesTone); mDialogPreference.setAquesTone2Requried(!AppManager.editorConfig.DoNotUseAquesTone2); mDialogPreference.setVocaloid1Required(!AppManager.editorConfig.DoNotUseVocaloid1); mDialogPreference.setVocaloid2Required(!AppManager.editorConfig.DoNotUseVocaloid2); mDialogPreference.setBufferSize(AppManager.editorConfig.BufferSizeMilliSeconds); mDialogPreference.setDefaultSynthesizer(AppManager.editorConfig.DefaultSynthesizer); mDialogPreference.setUseUserDefinedAutoVibratoType(AppManager.editorConfig.UseUserDefinedAutoVibratoType); mDialogPreference.setWinePrefix(AppManager.editorConfig.WinePrefix); mDialogPreference.setWineTop(AppManager.editorConfig.WineTop); mDialogPreference.setWineBuiltin(AppManager.editorConfig.WineTopBuiltin); mDialogPreference.setEnableWideCharacterWorkaround(AppManager.editorConfig.UseWideCharacterWorkaround); String old_wine_prefix = AppManager.editorConfig.WinePrefix; String old_wine_top = AppManager.editorConfig.getWineTop(); mDialogPreference.Location = location; //Show the special voicebank config menu if it's requested if (showVBCfg) { mDialogPreference.showEasySetupUtauVB(); } DialogResult dr = AppManager.showModalDialog(mDialogPreference, Parent); if (dr == DialogResult.OK) { String old_base_font_name = AppManager.editorConfig.BaseFontName; float old_base_font_size = AppManager.editorConfig.BaseFontSize; Font new_base_font = mDialogPreference.getBaseFont(); if (!old_base_font_name.Equals(new_base_font.getName()) || old_base_font_size != new_base_font.getSize2D()) { AppManager.editorConfig.BaseFontName = mDialogPreference.getBaseFont().getName(); AppManager.editorConfig.BaseFontSize = mDialogPreference.getBaseFont().getSize2D(); //updateMenuFonts(); } AppManager.editorConfig.ScreenFontName = mDialogPreference.getScreenFont().getName(); AppManager.editorConfig.WheelOrder = mDialogPreference.getWheelOrder(); AppManager.editorConfig.CursorFixed = mDialogPreference.isCursorFixed(); AppManager.editorConfig.DefaultVibratoLength = mDialogPreference.getDefaultVibratoLength(); AppManager.editorConfig.AutoVibratoThresholdLength = mDialogPreference.getAutoVibratoThresholdLength(); AppManager.editorConfig.AutoVibratoType1 = mDialogPreference.getAutoVibratoType1(); AppManager.editorConfig.AutoVibratoType2 = mDialogPreference.getAutoVibratoType2(); AppManager.editorConfig.AutoVibratoTypeCustom = mDialogPreference.getAutoVibratoTypeCustom(); AppManager.editorConfig.EnableAutoVibrato = mDialogPreference.isEnableAutoVibrato(); AppManager.editorConfig.PreSendTime = mDialogPreference.getPreSendTime(); AppManager.editorConfig.Language = mDialogPreference.getLanguage(); if (!Messaging.getLanguage().Equals(AppManager.editorConfig.Language)) { Messaging.setLanguage(AppManager.editorConfig.Language); //applyLanguage(); mDialogPreference.applyLanguage(); //AppManager.mMixerWindow.applyLanguage(); //if (mVersionInfo != null && !mVersionInfo.IsDisposed) { // mVersionInfo.applyLanguage(); //} #if ENABLE_PROPERTY AppManager.propertyWindow.applyLanguage(); AppManager.propertyPanel.updateValue(AppManager.getSelected()); #endif //if (mDialogMidiImportAndExport != null) { // mDialogMidiImportAndExport.applyLanguage(); //} } AppManager.editorConfig.ControlCurveResolution = mDialogPreference.getControlCurveResolution(); AppManager.editorConfig.DefaultSingerName = mDialogPreference.getDefaultSingerName(); AppManager.editorConfig.ScrollHorizontalOnWheel = mDialogPreference.isScrollHorizontalOnWheel(); AppManager.editorConfig.MaximumFrameRate = mDialogPreference.getMaximumFrameRate(); int fps = 1000 / AppManager.editorConfig.MaximumFrameRate; //timer.Interval = (fps <= 0) ? 1 : fps; //applyShortcut(); AppManager.editorConfig.KeepLyricInputMode = mDialogPreference.isKeepLyricInputMode(); if (AppManager.editorConfig.PxTrackHeight != mDialogPreference.getPxTrackHeight()) { AppManager.editorConfig.PxTrackHeight = mDialogPreference.getPxTrackHeight(); //updateDrawObjectList(); } AppManager.editorConfig.setMouseHoverTime(mDialogPreference.getMouseHoverTime()); AppManager.editorConfig.PlayPreviewWhenRightClick = mDialogPreference.isPlayPreviewWhenRightClick(); AppManager.editorConfig.CurveSelectingQuantized = mDialogPreference.isCurveSelectingQuantized(); AppManager.editorConfig.CurveVisibleAccent = mDialogPreference.isCurveVisibleAccent(); AppManager.editorConfig.CurveVisibleBreathiness = mDialogPreference.isCurveVisibleBre(); AppManager.editorConfig.CurveVisibleBrightness = mDialogPreference.isCurveVisibleBri(); AppManager.editorConfig.CurveVisibleClearness = mDialogPreference.isCurveVisibleCle(); AppManager.editorConfig.CurveVisibleDecay = mDialogPreference.isCurveVisibleDecay(); AppManager.editorConfig.CurveVisibleDynamics = mDialogPreference.isCurveVisibleDyn(); AppManager.editorConfig.CurveVisibleGendorfactor = mDialogPreference.isCurveVisibleGen(); AppManager.editorConfig.CurveVisibleOpening = mDialogPreference.isCurveVisibleOpe(); AppManager.editorConfig.CurveVisiblePit = mDialogPreference.isCurveVisiblePit(); AppManager.editorConfig.CurveVisiblePbs = mDialogPreference.isCurveVisiblePbs(); AppManager.editorConfig.CurveVisiblePortamento = mDialogPreference.isCurveVisiblePor(); AppManager.editorConfig.CurveVisibleVelocity = mDialogPreference.isCurveVisibleVel(); AppManager.editorConfig.CurveVisibleVibratoDepth = mDialogPreference.isCurveVisibleVibratoDepth(); AppManager.editorConfig.CurveVisibleVibratoRate = mDialogPreference.isCurveVisibleVibratoRate(); AppManager.editorConfig.CurveVisibleFx2Depth = mDialogPreference.isCurveVisibleFx2Depth(); AppManager.editorConfig.CurveVisibleHarmonics = mDialogPreference.isCurveVisibleHarmonics(); AppManager.editorConfig.CurveVisibleReso1 = mDialogPreference.isCurveVisibleReso1(); AppManager.editorConfig.CurveVisibleReso2 = mDialogPreference.isCurveVisibleReso2(); AppManager.editorConfig.CurveVisibleReso3 = mDialogPreference.isCurveVisibleReso3(); AppManager.editorConfig.CurveVisibleReso4 = mDialogPreference.isCurveVisibleReso4(); AppManager.editorConfig.CurveVisibleEnvelope = mDialogPreference.isCurveVisibleEnvelope(); #if ENABLE_MIDI AppManager.editorConfig.MidiInPort.PortNumber = mDialogPreference.getMidiInPort(); #endif #if ENABLE_MTC AppManager.editorConfig.MidiInPortMtc.PortNumber = m_preference_dlg.getMtcMidiInPort(); #endif #if ENABLE_MIDI || ENABLE_MTC //updateMidiInStatus(); //reloadMidiIn(); #endif Vector <String> new_resamplers = new Vector <String>(); Vector <Boolean> new_with_wine = new Vector <Boolean>(); mDialogPreference.copyResamplersConfig(new_resamplers, new_with_wine); AppManager.editorConfig.clearResampler(); for (int i = 0; i < new_resamplers.size(); i++) { AppManager.editorConfig.addResampler(new_resamplers.get(i), new_with_wine.get(i)); } AppManager.editorConfig.PathWavtool = mDialogPreference.getPathWavtool(); AppManager.editorConfig.WavtoolWithWine = mDialogPreference.isWavtoolWithWine(); AppManager.editorConfig.UtauSingers.clear(); for (Iterator <SingerConfig> itr = mDialogPreference.getUtausingers().iterator(); itr.hasNext();) { SingerConfig sc = itr.next(); AppManager.editorConfig.UtauSingers.add((SingerConfig)sc.clone()); } AppManager.reloadUtauVoiceDB(); AppManager.editorConfig.SelfDeRomanization = mDialogPreference.isSelfDeRomantization(); AppManager.editorConfig.AutoBackupIntervalMinutes = mDialogPreference.getAutoBackupIntervalMinutes(); AppManager.editorConfig.UseSpaceKeyAsMiddleButtonModifier = mDialogPreference.isUseSpaceKeyAsMiddleButtonModifier(); #if ENABLE_AQUESTONE var old_aquestone_config = Tuple.Create(AppManager.editorConfig.PathAquesTone, AppManager.editorConfig.DoNotUseAquesTone); AppManager.editorConfig.PathAquesTone = mDialogPreference.getPathAquesTone(); AppManager.editorConfig.DoNotUseAquesTone = !mDialogPreference.isAquesToneRequired(); if (old_aquestone_config.Item1 != AppManager.editorConfig.PathAquesTone || old_aquestone_config.Item2 != AppManager.editorConfig.DoNotUseAquesTone) { VSTiDllManager.reloadAquesTone(); } var old_aquestone2_config = Tuple.Create(AppManager.editorConfig.PathAquesTone2, AppManager.editorConfig.DoNotUseAquesTone2); AppManager.editorConfig.PathAquesTone2 = mDialogPreference.getPathAquesTone2(); AppManager.editorConfig.DoNotUseAquesTone2 = !mDialogPreference.isAquesTone2Required(); if (old_aquestone2_config.Item1 != AppManager.editorConfig.PathAquesTone2 || old_aquestone2_config.Item2 != AppManager.editorConfig.DoNotUseAquesTone2) { VSTiDllManager.reloadAquesTone2(); } #endif //updateRendererMenu(); //AppManager.editorConfig.__revoked__WaveFileOutputFromMasterTrack = mDialogPreference.isWaveFileOutputFromMasterTrack(); //AppManager.editorConfig.__revoked__WaveFileOutputChannel = mDialogPreference.getWaveFileOutputChannel(); if (AppManager.editorConfig.UseProjectCache && !mDialogPreference.isUseProjectCache()) { // プロジェクト用キャッシュを使用していたが,使用しないように変更された場合. // プロジェクト用キャッシュが存在するなら,共用のキャッシュに移動する. String file = AppManager.getFileName(); if (file != null && !file.Equals("")) { String dir = PortUtil.getDirectoryName(file); String name = PortUtil.getFileNameWithoutExtension(file); String projectCacheDir = Path.Combine(dir, name + ".cadencii"); String commonCacheDir = Path.Combine(AppManager.getCadenciiTempDir(), AppManager.getID()); if (Directory.Exists(projectCacheDir)) { VsqFileEx vsq = AppManager.getVsqFile(); for (int i = 1; i < vsq.Track.size(); i++) { // wavを移動 String wavFrom = Path.Combine(projectCacheDir, i + ".wav"); String wavTo = Path.Combine(commonCacheDir, i + ".wav"); if (!System.IO.File.Exists(wavFrom)) { continue; } if (System.IO.File.Exists(wavTo)) { try { PortUtil.deleteFile(wavTo); } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); serr.println("FormMain#menuSettingPreference_Click; ex=" + ex); continue; } } try { PortUtil.moveFile(wavFrom, wavTo); } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); serr.println("FormMain#menuSettingPreference_Click; ex=" + ex); } // xmlを移動 String xmlFrom = Path.Combine(projectCacheDir, i + ".xml"); String xmlTo = Path.Combine(commonCacheDir, i + ".xml"); if (!System.IO.File.Exists(xmlFrom)) { continue; } if (System.IO.File.Exists(xmlTo)) { try { PortUtil.deleteFile(xmlTo); } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); serr.println("FormMain#menuSettingPreference_Click; ex=" + ex); continue; } } try { PortUtil.moveFile(xmlFrom, xmlTo); } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); serr.println("FormMain#menuSettingPreference_Click; ex=" + ex); } } // projectCacheDirが空なら,ディレクトリごと削除する String[] files = PortUtil.listFiles(projectCacheDir, "*.*"); if (files.Length <= 0) { try { PortUtil.deleteDirectory(projectCacheDir); } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); serr.println("FormMain#menuSettingPreference_Click; ex=" + ex); } } // キャッシュのディレクトリを再指定 AppManager.setTempWaveDir(commonCacheDir); } } } AppManager.editorConfig.UseProjectCache = mDialogPreference.isUseProjectCache(); AppManager.editorConfig.DoNotUseVocaloid1 = !mDialogPreference.isVocaloid1Required(); AppManager.editorConfig.DoNotUseVocaloid2 = !mDialogPreference.isVocaloid2Required(); AppManager.editorConfig.BufferSizeMilliSeconds = mDialogPreference.getBufferSize(); AppManager.editorConfig.DefaultSynthesizer = mDialogPreference.getDefaultSynthesizer(); AppManager.editorConfig.UseUserDefinedAutoVibratoType = mDialogPreference.isUseUserDefinedAutoVibratoType(); AppManager.editorConfig.WinePrefix = mDialogPreference.getWinePrefix(); AppManager.editorConfig.WineTop = mDialogPreference.getWineTop(); AppManager.editorConfig.WineTopBuiltin = mDialogPreference.isWineBuiltin(); AppManager.editorConfig.UseWideCharacterWorkaround = mDialogPreference.isEnableWideCharacterWorkaround(); //trackSelector.prepareSingerMenu(VsqFileEx.getTrackRendererKind(AppManager.getVsqFile().Track.get(AppManager.getSelected()))); //trackSelector.updateVisibleCurves(); //updateRendererMenu(); AppManager.updateAutoBackupTimerStatus(); // editorConfig.PxTrackHeightが変更されている可能性があるので,更新が必要 //controller.setStartToDrawY(calculateStartToDrawY(vScroll.Value)); //if (menuVisualControlTrack.Checked) { // splitContainer1.setPanel2MinSize(trackSelector.getPreferredMinSize()); //} AppManager.saveConfig(); //applyLanguage(); #if ENABLE_SCRIPT //updateScriptShortcut(); #endif //updateDrawObjectList(); //refreshScreen(); } } catch (Exception ex) { Logger.write(typeof(FormMain) + ".menuSettingPreference_Click; ex=" + ex + "\n"); AppManager.debugWriteLine("FormMain#menuSettingPreference_Click; ex=" + ex); } }
public DrawObject(DrawObjectType type, VsqFileEx vsq, Rectangle rect, string text_, int accent_, int decay, int velocity, int internal_id, int vibrato_delay, bool overwrapped, bool symbol_protected, VibratoBPList vib_rate, VibratoBPList vib_depth, int vib_start_rate, int vib_start_depth, int note_, UstEnvelope ust_envelope, int length, int clock, bool is_valid_for_utau, bool is_valid_for_straight, int vib_delay, int intensity) { this.mType = type; mRectangleInPixel = rect; mText = text_; mAccent = accent_; mDecay = decay; mVelocity = velocity; mInternalID = internal_id; mVibratoDelayInPixel = vibrato_delay; mIsOverlapped = overwrapped; mIsSymbolProtected = symbol_protected; mIntensity = intensity; mNote = note_; mUstEnvelope = ust_envelope; this.mLength = length; this.mClock = clock; this.mIsValidForUtau = is_valid_for_utau; this.mIsValidForStraight = is_valid_for_straight; this.mVibDelay = vib_delay; int viblength = length - vib_delay; if (viblength > 0 && vib_rate != null && vib_depth != null) { VibratoPointIteratorByClock itr = new VibratoPointIteratorByClock(vsq.TempoTable, vib_rate, vib_start_rate, vib_depth, vib_start_depth, clock + vib_delay, viblength); mVibratoPit = new float[viblength]; for (int i = 0; i < viblength; i++) { if (!itr.hasNext()) { break; } double v = itr.next(); mVibratoPit[i] = (float)v; } } }
/// <summary> /// /// </summary> /// <param name="vsq"></param> /// <param name="track"></param> /// <param name="clock_start"></param> /// <param name="clock_end"></param> /// <returns></returns> private TreeMap<Integer, MidiEventQueue> generateMidiEvent( VsqFileEx vsq, int track, int clock_start, int clock_end ) { TreeMap<Integer, MidiEventQueue> list = new TreeMap<Integer, MidiEventQueue>(); VsqTrack t = vsq.Track.get( track ); // 歌手変更 for ( Iterator<VsqEvent> itr = t.getSingerEventIterator(); itr.hasNext(); ) { VsqEvent item = itr.next(); if ( clock_start <= item.Clock && item.Clock <= clock_end ) { if ( item.ID.IconHandle == null ) { continue; } int program = item.ID.IconHandle.Program; if ( 0 > program || program >= AquesToneDriver.SINGERS.Length ) { program = 0; } ParameterEvent singer = new ParameterEvent(); singer.index = mDriver.phontParameterIndex; singer.value = program + 0.01f; if ( !list.containsKey( item.Clock ) ) { list.put( item.Clock, new MidiEventQueue() ); } MidiEventQueue queue = list.get( item.Clock ); if ( queue.param == null ) { queue.param = new Vector<ParameterEvent>(); } queue.param.add( singer ); } else if ( clock_end < item.Clock ) { break; } } // ノート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イベントを作成 String lyric = item.ID.LyricHandle.L0.Phrase; String katakana = KanaDeRomanization.hiragana2katakana( KanaDeRomanization.Attach( lyric ) ); int index = -1; for ( int i = 0; i < AquesToneDriver.PHONES.Length; i++ ) { if ( katakana.Equals( AquesToneDriver.PHONES[i] ) ) { index = i; break; } } if ( index >= 0 ) { if ( !list.containsKey( item.Clock ) ) { list.put( item.Clock, new MidiEventQueue() ); } MidiEventQueue queue = list.get( item.Clock ); if ( queue.noteon == null ) { queue.noteon = new Vector<MidiEvent>(); } // index行目に移動するコマンドを贈る MidiEvent moveline = new MidiEvent(); moveline.firstByte = 0xb0; moveline.data = new[] { 0x0a, index }; MidiEvent noteon = new MidiEvent(); noteon.firstByte = 0x90; noteon.data = new int[] { item.ID.Note, item.ID.Dynamics }; Vector<MidiEvent> add = Arrays.asList( new MidiEvent[] { moveline, noteon } ); queue.noteon.addAll( add ); pit_send.add( new Point( item.Clock, item.Clock ) ); } /* 音符頭で設定するパラメータ */ // Release MidiEventQueue q = null; if ( !list.containsKey( item.Clock ) ) { q = new MidiEventQueue(); } else { q = list.get( item.Clock ); } if ( q.param == null ) { q.param = new Vector<ParameterEvent>(); } String strRelease = VsqFileEx.getEventTag( item, VsqFileEx.TAG_VSQEVENT_AQUESTONE_RELEASE ); int release = 64; try { release = str.toi( 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 ); if ( !list.containsKey( item.Clock ) ) { list.put( item.Clock, new MidiEventQueue() ); } MidiEventQueue queue = list.get( item.Clock ); if ( queue.pit == null ) { queue.pit = new Vector<MidiEvent>(); } else { 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; if ( queue.param == null ) { queue.param = new Vector<ParameterEvent>(); } 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; } if ( !list.containsKey( item.Clock ) ) { list.put( item.Clock, new MidiEventQueue() ); } MidiEventQueue queue = list.get( item.Clock ); ParameterEvent pe = new ParameterEvent(); pe.index = mDriver.bendLblParameterIndex; pe.value = required_pbs / 13.0f; if ( queue.param == null ) { queue.param = new Vector<ParameterEvent>(); } 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); if ( !list.containsKey( clock ) ) { list.put( clock, new MidiEventQueue() ); } MidiEventQueue q = list.get( clock ); MidiEvent me = getPitMidiEvent( pit_value ); if ( q.pit == null ) { q.pit = new Vector<MidiEvent>(); } else { 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 } ); if ( !list.containsKey( endclock ) ) { list.put( endclock, new MidiEventQueue() ); } MidiEventQueue q = list.get( endclock ); if ( q.noteoff == null ) { q.noteoff = new Vector<MidiEvent>(); } 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 = null; if ( list.containsKey( clock ) ) { queue = list.get( clock ); } else { queue = new MidiEventQueue(); } if ( queue.param == null ) { queue.param = new Vector<ParameterEvent>(); } queue.param.add( pbse ); list.put( clock, queue ); } 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 = null; if ( list.containsKey( clock ) ) { queue = list.get( clock ); } else { queue = new MidiEventQueue(); } if ( queue.pit == null ) { queue.pit = new Vector<MidiEvent>(); } else { queue.pit.clear(); } queue.pit.add( pbs0 ); list.put( clock, queue ); } 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; }
public static ScriptReturnStatus Edit( VsqFileEx vsq ) { UtauPluginManager dialog = new UtauPluginManager(); dialog.ShowDialog(); return ScriptReturnStatus.NOT_EDITED; }
/// <summary> /// スクリプトを実行します。 /// </summary> /// <param name="evsd"></param> public static boolean invokeScript(String id, VsqFileEx vsq) { ScriptInvoker script_invoker = null; if (scripts.containsKey(id)) { script_invoker = scripts.get(id); } else { return(false); } if (script_invoker != null && script_invoker.scriptDelegate != null) { try { VsqFileEx work = (VsqFileEx)vsq.clone(); ScriptReturnStatus ret = ScriptReturnStatus.ERROR; if (script_invoker.scriptDelegate is EditVsqScriptDelegate) { boolean b_ret = ((EditVsqScriptDelegate)script_invoker.scriptDelegate).Invoke(work); if (b_ret) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateEx) { boolean b_ret = ((EditVsqScriptDelegateEx)script_invoker.scriptDelegate).Invoke(work); if (b_ret) { ret = ScriptReturnStatus.EDITED; } else { ret = ScriptReturnStatus.ERROR; } } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateWithStatus) { ret = ((EditVsqScriptDelegateWithStatus)script_invoker.scriptDelegate).Invoke(work); } else if (script_invoker.scriptDelegate is EditVsqScriptDelegateExWithStatus) { ret = ((EditVsqScriptDelegateExWithStatus)script_invoker.scriptDelegate).Invoke(work); } else { ret = ScriptReturnStatus.ERROR; } if (ret == ScriptReturnStatus.ERROR) { AppManager.showMessageBox(_("Script aborted"), "Cadencii", cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE); } else if (ret == ScriptReturnStatus.EDITED) { CadenciiCommand run = VsqFileEx.generateCommandReplace(work); AppManager.editHistory.register(vsq.executeCommand(run)); } String config_file = configFileNameFromScriptFileName(script_invoker.ScriptFile); FileOutputStream fs = null; boolean delete_xml_when_exit = false; // xmlを消すときtrue try { fs = new FileOutputStream(config_file); script_invoker.Serializer.serialize(fs, null); } catch (Exception ex) { serr.println("AppManager#invokeScript; ex=" + ex); delete_xml_when_exit = true; } finally { if (fs != null) { try { fs.close(); if (delete_xml_when_exit) { PortUtil.deleteFile(config_file); } } catch (Exception ex2) { serr.println("AppManager#invokeScript; ex2=" + ex2); } } } return(ret == ScriptReturnStatus.EDITED); } catch (Exception ex) { AppManager.showMessageBox(_("Script runtime error:") + " " + ex, _("Error"), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_INFORMATION_MESSAGE); serr.println("AppManager#invokeScript; ex=" + ex); } } else { AppManager.showMessageBox(_("Script compilation failed."), _("Error"), cadencii.windows.forms.Utility.MSGBOX_DEFAULT_OPTION, cadencii.windows.forms.Utility.MSGBOX_WARNING_MESSAGE); } return(false); }
public void draw(Graphics2D g, int width, int height) { if (mMainForm == null) { return; } lock (AppManager.mDrawObjects) { g.setColor(mBackgroundColor); g.fillRect(0, 0, width, height); g.setStroke(getStroke2px()); g.setColor(FormMain.mColorNoteFill); int key_width = AppManager.keyWidth; int xoffset = key_width + AppManager.keyOffset; VsqFileEx vsq = AppManager.getVsqFile(); int overview_dot_diam = 2; int selected = AppManager.getSelected(); List <DrawObject> objs = AppManager.mDrawObjects[selected - 1]; // 平均ノートナンバーを調べる double sum = 0.0; int count = 0; foreach (var dobj in objs) { if (dobj.mType == DrawObjectType.Note) { sum += dobj.mNote; count++; } } float average_note = (float)(sum / (double)count); foreach (var dobj in objs) { int x = (int)(dobj.mClock * mOverviewPixelPerClock); if (x < 0) { continue; } if (width - key_width < x) { break; } int y = height - (height / 2 + (int)((dobj.mNote - average_note) * overview_dot_diam)); int length = (int)(dobj.mLength * mOverviewPixelPerClock); if (length < overview_dot_diam) { length = overview_dot_diam; } g.drawLine(x + xoffset, y, x + length + xoffset, y); } g.setStroke(getStrokeDefault()); int current_start = AppManager.clockFromXCoord(key_width); int current_end = AppManager.clockFromXCoord(mMainForm.pictPianoRoll.getWidth()); int x_start = (int)(current_start * mOverviewPixelPerClock); int x_end = (int)(current_end * mOverviewPixelPerClock); // 小節ごとの線 int clock_start = 0; int clock_end = (int)(width / mOverviewPixelPerClock); int premeasure = vsq.getPreMeasure(); g.setClip(null); Color pen_color = new java.awt.Color(0, 0, 0, 130); int barcountx = 0; string barcountstr = ""; for (Iterator <VsqBarLineType> itr = vsq.getBarLineIterator(clock_end * 3 / 2); itr.hasNext();) { VsqBarLineType bar = itr.next(); if (bar.clock() < clock_start) { continue; } if (width - key_width < barcountx) { break; } if (bar.isSeparator()) { int barcount = bar.getBarCount() - premeasure + 1; int x = (int)(bar.clock() * mOverviewPixelPerClock); if ((barcount % 5 == 0 && barcount > 0) || barcount == 1) { g.setColor(pen_color); g.setStroke(getStroke2px()); g.drawLine(x + xoffset, 0, x + xoffset, height); g.setStroke(getStrokeDefault()); if (!barcountstr.Equals("")) { g.setColor(Color.white); g.setFont(AppManager.baseFont9); g.drawString(barcountstr, barcountx + 1 + xoffset, 1 + AppManager.baseFont9Height / 2 - AppManager.baseFont9OffsetHeight + 1); } barcountstr = barcount + ""; barcountx = x; } else { g.setColor(pen_color); g.drawLine(x + xoffset, 0, x + xoffset, height); } } } g.setClip(null); } }
public static void GenerateSinglePhone(int note, string singer, string file, double amp) { string renderer = ""; SingerConfig[] singers1 = VocaloSysUtil.getSingerConfigs(SynthesizerType.VOCALOID1); int c = singers1.Length; string first_found_singer = ""; string first_found_renderer = ""; for (int i = 0; i < c; i++) { if (first_found_singer.Equals("")) { first_found_singer = singers1[i].VOICENAME; first_found_renderer = VsqFileEx.RENDERER_DSB2; } if (singers1[i].VOICENAME.Equals(singer)) { renderer = VsqFileEx.RENDERER_DSB2; break; } } SingerConfig[] singers2 = VocaloSysUtil.getSingerConfigs(SynthesizerType.VOCALOID2); c = singers2.Length; for (int i = 0; i < c; i++) { if (first_found_singer.Equals("")) { first_found_singer = singers2[i].VOICENAME; first_found_renderer = VsqFileEx.RENDERER_DSB3; } if (singers2[i].VOICENAME.Equals(singer)) { renderer = VsqFileEx.RENDERER_DSB3; break; } } foreach (var sc in AppManager.editorConfig.UtauSingers) { if (first_found_singer.Equals("")) { first_found_singer = sc.VOICENAME; first_found_renderer = VsqFileEx.RENDERER_UTU0; } if (sc.VOICENAME.Equals(singer)) { renderer = VsqFileEx.RENDERER_UTU0; break; } } VsqFileEx vsq = new VsqFileEx(singer, 1, 4, 4, 500000); if (renderer.Equals("")) { singer = first_found_singer; renderer = first_found_renderer; } vsq.Track[1].getCommon().Version = renderer; VsqEvent item = new VsqEvent(1920, new VsqID(0)); item.ID.LyricHandle = new LyricHandle("あ", "a"); item.ID.setLength(480); item.ID.Note = note; item.ID.VibratoHandle = null; item.ID.type = VsqIDType.Anote; vsq.Track[1].addEvent(item); vsq.updateTotalClocks(); int ms_presend = 500; string tempdir = Path.Combine(AppManager.getCadenciiTempDir(), AppManager.getID()); if (!Directory.Exists(tempdir)) { try { PortUtil.createDirectory(tempdir); } catch (Exception ex) { Logger.write(typeof(FormGenerateKeySound) + ".GenerateSinglePhone; ex=" + ex + "\n"); serr.println("Program#GenerateSinglePhone; ex=" + ex); return; } } WaveWriter ww = null; try { ww = new WaveWriter(file); RendererKind kind = VsqFileEx.getTrackRendererKind(vsq.Track[1]); WaveGenerator generator = VSTiDllManager.getWaveGenerator(kind); int sample_rate = vsq.config.SamplingRate; FileWaveReceiver receiver = new FileWaveReceiver(file, 1, 16, sample_rate); generator.setReceiver(receiver); generator.setGlobalConfig(AppManager.editorConfig); #if DEBUG sout.println("FormGenerateKeySound#GenerateSinglePhone; sample_rate=" + sample_rate); #endif generator.init(vsq, 1, 0, vsq.TotalClocks, sample_rate); double total_sec = vsq.getSecFromClock(vsq.TotalClocks) + 1.0; WorkerStateImp state = new WorkerStateImp(); generator.begin((long)(total_sec * sample_rate), state); } catch (Exception ex) { serr.println("FormGenerateKeySound#GenerateSinglePhone; ex=" + ex); Logger.write(typeof(FormGenerateKeySound) + ".GenerateSinglePhone; ex=" + ex + "\n"); } finally { if (ww != null) { try { ww.close(); } catch (Exception ex2) { Logger.write(typeof(FormGenerateKeySound) + ".GenerateSinglePhone; ex=" + ex2 + "\n"); serr.println("FormGenerateKeySound#GenerateSinglePhone; ex2=" + ex2); } } } }
public EventQueueSequence generateMidiEvent( VsqFileEx vsq, int track ) { return base.generateMidiEvent( vsq, track ); }
protected abstract EventQueueSequence generateMidiEvent(VsqFileEx vsq, int track, int clock_start, int clock_end);
/// <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(); }