(メッセージはありません)
@@ -239,8 +239,8 @@ | ||
239 | 239 | #endif // !UNMANAGED_VSTIDRV |
240 | 240 | |
241 | 241 | try { |
242 | -#if DEBUG | |
243 | - s_dll_path = @"C:\Program Files\Steinberg\VSTplugins\utauvsti.dll"; | |
242 | +#if TEST | |
243 | + s_dll_path = @"C:\Program Files\Steinberg\VSTplugins\utauvsti\utauvsti.dll"; | |
244 | 244 | #endif |
245 | 245 | char[] str = s_dll_path.ToCharArray(); |
246 | 246 | if ( s_dll_path != "" ) { |
@@ -659,7 +659,14 @@ | ||
659 | 659 | } |
660 | 660 | |
661 | 661 | static void vstidrv_WaveIncoming( double[] L, double[] R ) { |
662 | +#if DEBUG | |
663 | + Common.DebugWriteLine( "VSTiProxy.vstidrv_WaveIncoming" ); | |
664 | + Common.DebugWriteLine( " requiring lock of s_locker..." ); | |
665 | +#endif | |
662 | 666 | lock ( s_locker ) { |
667 | +#if DEBUG | |
668 | + Common.DebugWriteLine( " ...done" ); | |
669 | +#endif | |
663 | 670 | if ( s_trim_remain > 0 ) { |
664 | 671 | if ( s_trim_remain >= L.Length ) { |
665 | 672 | s_trim_remain -= L.Length; |
@@ -763,8 +770,8 @@ | ||
763 | 770 | s_rendering_finished_callback = new __RenderingFinishedCallback( HandleRenderingFinishedCallback ); |
764 | 771 | try { |
765 | 772 | vstidrv_setFirstBufferWrittenCallback( Marshal.GetFunctionPointerForDelegate( s_first_buffer_written_callback ) ); |
766 | - vstidrv_setWaveIncomingCallback( s_wave_incoming_callback ); | |
767 | - vstidrv_setRenderingFinishedCallback( s_rendering_finished_callback ); | |
773 | + vstidrv_setWaveIncomingCallback( Marshal.GetFunctionPointerForDelegate( s_wave_incoming_callback ) ); | |
774 | + vstidrv_setRenderingFinishedCallback( Marshal.GetFunctionPointerForDelegate( s_rendering_finished_callback ) ); | |
768 | 775 | } catch ( Exception ex ) { |
769 | 776 | #if DEBUG |
770 | 777 | Common.DebugWriteLine( "vstidrv.cctor()" ); |
@@ -785,6 +792,9 @@ | ||
785 | 792 | } |
786 | 793 | |
787 | 794 | private static void HandleWaveIncomingCallback( double* L, double* R, int length ) { |
795 | +#if DEBUG | |
796 | + Common.DebugWriteLine( "vstidrv.HandleWaveIncomingCallback" ); | |
797 | +#endif | |
788 | 798 | if ( WaveIncoming != null ) { |
789 | 799 | double[] ret_l = new double[length]; |
790 | 800 | double[] ret_r = new double[length]; |
@@ -907,7 +917,7 @@ | ||
907 | 917 | public static float GetPlayTime() { |
908 | 918 | float ret = -1.0f; |
909 | 919 | #if DEBUG |
910 | - Common.DebugWriteLine( "vstidrv+GetPlayTime" ); | |
920 | + //Common.DebugWriteLine( "vstidrv+GetPlayTime" ); | |
911 | 921 | #endif |
912 | 922 | try { |
913 | 923 | ret = vstidrv_GetPlayTime(); |
@@ -994,11 +1004,11 @@ | ||
994 | 1004 | |
995 | 1005 | //void vstidrv_setWaveIncomingCallback( WaveIncomingCallback proc ); |
996 | 1006 | [DllImport( "vstidrv.dll" )] |
997 | - private static extern void vstidrv_setWaveIncomingCallback( __WaveIncomingCallback proc ); | |
1007 | + private static extern void vstidrv_setWaveIncomingCallback( IntPtr proc ); | |
998 | 1008 | |
999 | 1009 | //void vstidrv_setRenderingFinishedCallback( RenderingFinishedCallback proc ); |
1000 | 1010 | [DllImport( "vstidrv.dll" )] |
1001 | - private static extern void vstidrv_setRenderingFinishedCallback( __RenderingFinishedCallback proc ); | |
1011 | + private static extern void vstidrv_setRenderingFinishedCallback( IntPtr proc ); | |
1002 | 1012 | |
1003 | 1013 | //bool vstidrv_Init( string dll_path, int block_size, int sample_rate ); |
1004 | 1014 | [DllImport( "vstidrv.dll" )] |
@@ -252,6 +252,9 @@ | ||
252 | 252 | } |
253 | 253 | |
254 | 254 | private void ReloadMidiIn() { |
255 | +#if DEBUG | |
256 | + Common.DebugWriteLine( "FormMain.ReloadMidiIn" ); | |
257 | +#endif | |
255 | 258 | if ( m_midi_in != null ) { |
256 | 259 | m_midi_in.MidiReceived -= m_midi_in_MidiReceived; |
257 | 260 | m_midi_in.Dispose(); |
@@ -259,8 +262,12 @@ | ||
259 | 262 | try { |
260 | 263 | m_midi_in = new MidiInDevice( AppManager.EditorConfig.MidiInPort ); |
261 | 264 | m_midi_in.MidiReceived += m_midi_in_MidiReceived; |
262 | - } catch { | |
265 | + } catch (Exception ex ){ | |
266 | +#if DEBUG | |
267 | + Common.DebugWriteLine( " ex=" + ex ); | |
268 | +#endif | |
263 | 269 | } |
270 | + UpdateMidiInStatus(); | |
264 | 271 | } |
265 | 272 | |
266 | 273 | private void m_midi_in_MidiReceived( DateTime time, byte[] data ) { |
@@ -271,6 +278,10 @@ | ||
271 | 278 | return; |
272 | 279 | } |
273 | 280 | int code = data[0] & 0xf0; |
281 | +#if DEBUG | |
282 | + Common.DebugWriteLine( "m_midi_in_MidiReceived" ); | |
283 | + Common.DebugWriteLine( " code=0x" + Convert.ToString( code, 16 ) ); | |
284 | +#endif | |
274 | 285 | if ( code != 0x80 && code != 0x90 ) { |
275 | 286 | return; |
276 | 287 | } |
@@ -866,9 +877,13 @@ | ||
866 | 877 | } |
867 | 878 | |
868 | 879 | private void RefreshScreen() { |
880 | +#if DEBUG | |
881 | + RefreshScreenCore(); | |
882 | +#else | |
869 | 883 | if ( !bgWorkScreen.IsBusy ) { |
870 | 884 | bgWorkScreen.RunWorkerAsync(); |
871 | 885 | } |
886 | +#endif | |
872 | 887 | } |
873 | 888 | |
874 | 889 | public void FlipMixerDialogVisible( bool visible ) { |
@@ -2409,74 +2424,82 @@ | ||
2409 | 2424 | /// 描画すべきオブジェクトのリスト,m_draw_objectsを更新します |
2410 | 2425 | /// </summary> |
2411 | 2426 | private void UpdateDrawObjectList() { |
2412 | - if ( m_manager.VsqFile == null ) { | |
2413 | - return; | |
2427 | + if ( m_draw_objects == null ) { | |
2428 | + m_draw_objects = new List<List<DrawObject>>(); | |
2414 | 2429 | } |
2415 | - if ( m_draw_objects != null ) { | |
2416 | - foreach ( List<DrawObject> list in m_draw_objects ) { | |
2417 | - list.Clear(); | |
2430 | + lock ( m_draw_objects ) { | |
2431 | + if ( m_manager.VsqFile == null ) { | |
2432 | + return; | |
2418 | 2433 | } |
2419 | - m_draw_objects.Clear(); | |
2420 | - } | |
2421 | - m_draw_objects = new List<List<DrawObject>>(); | |
2434 | + for ( int i = 0; i < m_draw_start_index.Length; i++ ) { | |
2435 | + m_draw_start_index[i] = 0; | |
2436 | + } | |
2437 | + if ( m_draw_objects != null ) { | |
2438 | + foreach ( List<DrawObject> list in m_draw_objects ) { | |
2439 | + list.Clear(); | |
2440 | + } | |
2441 | + m_draw_objects.Clear(); | |
2442 | + } | |
2443 | + //m_draw_objects = new List<List<DrawObject>>(); | |
2422 | 2444 | |
2423 | - int xoffset = 6 + AppManager._KEY_LENGTH; | |
2424 | - int yoffset = 127 * AppManager.EditorConfig.PxTrackHeight; | |
2425 | - float scalex = m_manager.ScaleX; | |
2426 | - using ( Font SMALL_FONT = new Font( AppManager.EditorConfig.ScreenFontName, 8 ) ) { | |
2427 | - for ( int track = 1; track < m_manager.VsqFile.Tracks.Count; track++ ) { | |
2428 | - List<DrawObject> tmp = new List<DrawObject>(); | |
2429 | - foreach ( VsqEvent ev in m_manager.VsqFile.Tracks[track].Events ) { | |
2430 | - int timesig = ev.Clock; | |
2431 | - if ( ev.ID.LyricHandle != null ) { | |
2432 | - int length = ev.ID.Length; | |
2433 | - int note = ev.ID.Note; | |
2434 | - int x = (int)(timesig * scalex + xoffset); | |
2435 | - int y = -note * AppManager.EditorConfig.PxTrackHeight + yoffset; | |
2436 | - int lyric_width = (int)(length * scalex); | |
2437 | - string lyric_jp = ev.ID.LyricHandle.L0.Phrase; | |
2438 | - string lyric_en = ev.ID.LyricHandle.L0.PhoneticSymbol; | |
2439 | - string title = Common.TrimString( lyric_jp + " [" + lyric_en + "]", SMALL_FONT, lyric_width ); | |
2440 | - int accent = ev.ID.DEMaccent; | |
2441 | - int vibrato_start = x + lyric_width; | |
2442 | - int vibrato_end = x; | |
2443 | - int vibrato_delay = lyric_width * 2; | |
2444 | - if ( ev.ID.VibratoHandle != null ) { | |
2445 | - double rate = (double)ev.ID.VibratoDelay / (double)length; | |
2446 | - vibrato_delay = _PX_ACCENT_HEADER + (int)((lyric_width - _PX_ACCENT_HEADER) * rate); | |
2445 | + int xoffset = 6 + AppManager._KEY_LENGTH; | |
2446 | + int yoffset = 127 * AppManager.EditorConfig.PxTrackHeight; | |
2447 | + float scalex = m_manager.ScaleX; | |
2448 | + using ( Font SMALL_FONT = new Font( AppManager.EditorConfig.ScreenFontName, 8 ) ) { | |
2449 | + for ( int track = 1; track < m_manager.VsqFile.Tracks.Count; track++ ) { | |
2450 | + List<DrawObject> tmp = new List<DrawObject>(); | |
2451 | + foreach ( VsqEvent ev in m_manager.VsqFile.Tracks[track].Events ) { | |
2452 | + int timesig = ev.Clock; | |
2453 | + if ( ev.ID.LyricHandle != null ) { | |
2454 | + int length = ev.ID.Length; | |
2455 | + int note = ev.ID.Note; | |
2456 | + int x = (int)(timesig * scalex + xoffset); | |
2457 | + int y = -note * AppManager.EditorConfig.PxTrackHeight + yoffset; | |
2458 | + int lyric_width = (int)(length * scalex); | |
2459 | + string lyric_jp = ev.ID.LyricHandle.L0.Phrase; | |
2460 | + string lyric_en = ev.ID.LyricHandle.L0.PhoneticSymbol; | |
2461 | + string title = Common.TrimString( lyric_jp + " [" + lyric_en + "]", SMALL_FONT, lyric_width ); | |
2462 | + int accent = ev.ID.DEMaccent; | |
2463 | + int vibrato_start = x + lyric_width; | |
2464 | + int vibrato_end = x; | |
2465 | + int vibrato_delay = lyric_width * 2; | |
2466 | + if ( ev.ID.VibratoHandle != null ) { | |
2467 | + double rate = (double)ev.ID.VibratoDelay / (double)length; | |
2468 | + vibrato_delay = _PX_ACCENT_HEADER + (int)((lyric_width - _PX_ACCENT_HEADER) * rate); | |
2469 | + } | |
2470 | + tmp.Add( new DrawObject( new Rectangle( x, y, lyric_width, AppManager.EditorConfig.PxTrackHeight ), | |
2471 | + title, | |
2472 | + accent, | |
2473 | + ev.InternalID, | |
2474 | + vibrato_delay, | |
2475 | + false, | |
2476 | + ev.ID.LyricHandle.L0.PhoneticSymbolProtected ) ); | |
2447 | 2477 | } |
2448 | - tmp.Add( new DrawObject( new Rectangle( x, y, lyric_width, AppManager.EditorConfig.PxTrackHeight ), | |
2449 | - title, | |
2450 | - accent, | |
2451 | - ev.InternalID, | |
2452 | - vibrato_delay, | |
2453 | - false, | |
2454 | - ev.ID.LyricHandle.L0.PhoneticSymbolProtected ) ); | |
2455 | 2478 | } |
2456 | - } | |
2457 | 2479 | |
2458 | - // 重複部分があるかどうかを判定 | |
2459 | - for ( int i = 0; i < tmp.Count - 1; i++ ) { | |
2460 | - bool overwrapped = false; | |
2461 | - for ( int j = i + 1; j < tmp.Count; j++ ) { | |
2462 | - int startx = tmp[j].pxRectangle.X; | |
2463 | - int endx = tmp[j].pxRectangle.X + tmp[j].pxRectangle.Width; | |
2464 | - if ( startx < tmp[i].pxRectangle.X ) { | |
2465 | - if ( tmp[i].pxRectangle.X < endx ) { | |
2480 | + // 重複部分があるかどうかを判定 | |
2481 | + for ( int i = 0; i < tmp.Count - 1; i++ ) { | |
2482 | + bool overwrapped = false; | |
2483 | + for ( int j = i + 1; j < tmp.Count; j++ ) { | |
2484 | + int startx = tmp[j].pxRectangle.X; | |
2485 | + int endx = tmp[j].pxRectangle.X + tmp[j].pxRectangle.Width; | |
2486 | + if ( startx < tmp[i].pxRectangle.X ) { | |
2487 | + if ( tmp[i].pxRectangle.X < endx ) { | |
2488 | + overwrapped = true; | |
2489 | + tmp[j].Overwrapped = true; | |
2490 | + // breakできない.2個以上の重複を検出する必要があるので. | |
2491 | + } | |
2492 | + } else if ( tmp[i].pxRectangle.X <= startx && startx < tmp[i].pxRectangle.X + tmp[i].pxRectangle.Width ) { | |
2466 | 2493 | overwrapped = true; |
2467 | 2494 | tmp[j].Overwrapped = true; |
2468 | - // breakできない.2個以上の重複を検出する必要があるので. | |
2469 | 2495 | } |
2470 | - } else if ( tmp[i].pxRectangle.X <= startx && startx < tmp[i].pxRectangle.X + tmp[i].pxRectangle.Width ) { | |
2471 | - overwrapped = true; | |
2472 | - tmp[j].Overwrapped = true; | |
2473 | 2496 | } |
2497 | + if ( overwrapped ) { | |
2498 | + tmp[i].Overwrapped = true; | |
2499 | + } | |
2474 | 2500 | } |
2475 | - if ( overwrapped ) { | |
2476 | - tmp[i].Overwrapped = true; | |
2477 | - } | |
2501 | + m_draw_objects.Add( tmp ); | |
2478 | 2502 | } |
2479 | - m_draw_objects.Add( tmp ); | |
2480 | 2503 | } |
2481 | 2504 | } |
2482 | 2505 | } |
@@ -2708,34 +2731,35 @@ | ||
2708 | 2731 | if ( m_draw_objects != null ) { |
2709 | 2732 | if ( m_manager.Overlay ) { |
2710 | 2733 | // まず、選択されていないトラックの簡易表示を行う |
2711 | - for ( int i = 0; i < m_draw_objects.Count; i++ ) { | |
2712 | - if ( i == m_manager.Selected - 1 ) { | |
2713 | - continue; | |
2714 | - } | |
2715 | - int j_start = m_draw_start_index[i]; | |
2716 | - bool first = true; | |
2717 | - for ( int j = j_start; j < m_draw_objects[i].Count; j++ ) { | |
2718 | - DrawObject dobj = m_draw_objects[i][j]; | |
2719 | - int x = dobj.pxRectangle.X - start_draw_x; | |
2720 | - y = dobj.pxRectangle.Y - start_draw_y; | |
2721 | - int lyric_width = dobj.pxRectangle.Width; | |
2722 | - if ( x + lyric_width < 0 ) { | |
2734 | + lock ( m_draw_objects ) { | |
2735 | + for ( int i = 0; i < m_draw_objects.Count; i++ ) { | |
2736 | + if ( i == m_manager.Selected - 1 ) { | |
2723 | 2737 | continue; |
2724 | - } else if ( width < x ) { | |
2725 | - break; | |
2726 | 2738 | } |
2727 | - if ( m_manager.Playing && first ) { | |
2728 | - m_draw_start_index[i] = j; | |
2729 | - first = false; | |
2730 | - } | |
2731 | - if ( y + AppManager.EditorConfig.PxTrackHeight < 0 || y > height ) { | |
2732 | - continue; | |
2733 | - } | |
2734 | - g.DrawLine( new Pen( AppManager.s_HILIGHT[i] ), | |
2735 | - new Point( x + 1, y + 7 ), | |
2736 | - new Point( x + lyric_width - 1, y + 7 ) ); | |
2737 | - g.DrawPolygon( new Pen( s_HIDDEN[i] ), | |
2738 | - new Point[] { | |
2739 | + int j_start = m_draw_start_index[i]; | |
2740 | + bool first = true; | |
2741 | + for ( int j = j_start; j < m_draw_objects[i].Count; j++ ) { | |
2742 | + DrawObject dobj = m_draw_objects[i][j]; | |
2743 | + int x = dobj.pxRectangle.X - start_draw_x; | |
2744 | + y = dobj.pxRectangle.Y - start_draw_y; | |
2745 | + int lyric_width = dobj.pxRectangle.Width; | |
2746 | + if ( x + lyric_width < 0 ) { | |
2747 | + continue; | |
2748 | + } else if ( width < x ) { | |
2749 | + break; | |
2750 | + } | |
2751 | + if ( m_manager.Playing && first ) { | |
2752 | + m_draw_start_index[i] = j; | |
2753 | + first = false; | |
2754 | + } | |
2755 | + if ( y + AppManager.EditorConfig.PxTrackHeight < 0 || y > height ) { | |
2756 | + continue; | |
2757 | + } | |
2758 | + g.DrawLine( new Pen( AppManager.s_HILIGHT[i] ), | |
2759 | + new Point( x + 1, y + 7 ), | |
2760 | + new Point( x + lyric_width - 1, y + 7 ) ); | |
2761 | + g.DrawPolygon( new Pen( s_HIDDEN[i] ), | |
2762 | + new Point[] { | |
2739 | 2763 | new Point( x, y + 7 ), |
2740 | 2764 | new Point( x + 1, y + 6 ), |
2741 | 2765 | new Point( x + lyric_width - 1, y + 6 ), |
@@ -2744,6 +2768,7 @@ | ||
2744 | 2768 | new Point( x + 1, y + 8 ), |
2745 | 2769 | new Point( x, y + 7 ) |
2746 | 2770 | } ); |
2771 | + } | |
2747 | 2772 | } |
2748 | 2773 | } |
2749 | 2774 | } |
@@ -2754,86 +2779,98 @@ | ||
2754 | 2779 | bool show_exp_line = AppManager.EditorConfig.ShowExpLine; |
2755 | 2780 | if ( selected >= 1 ) { |
2756 | 2781 | int j_start = m_draw_start_index[selected - 1]; |
2782 | + | |
2757 | 2783 | bool first = true; |
2758 | - for ( int j = j_start; j < m_draw_objects[selected - 1].Count; j++ ) { | |
2759 | - DrawObject dobj = m_draw_objects[selected - 1][j]; | |
2760 | - int x = dobj.pxRectangle.X - start_draw_x; | |
2761 | - y = dobj.pxRectangle.Y - start_draw_y; | |
2762 | - int lyric_width = dobj.pxRectangle.Width; | |
2763 | - if ( x + lyric_width < 0 ) { | |
2764 | - continue; | |
2765 | - } else if ( width < x ) { | |
2766 | - break; | |
2784 | + lock ( m_draw_objects ) { //ここでロックを取得しないと、描画中にUpdateDrawObjectのサイズが0になる可能性がある | |
2785 | +#if DEBUG | |
2786 | + if ( m_manager.EditMode == EditMode.Realtime ) { | |
2787 | + bocoree.debug.push_log( "FormMainUtil.DrawTo" ); | |
2788 | + bocoree.debug.push_log( " j_start=" + j_start ); | |
2789 | + bocoree.debug.push_log( " selected=" + selected ); | |
2790 | + bocoree.debug.push_log( " m_draw_objects[selected-1].Count=" + m_draw_objects[selected - 1].Count ); | |
2767 | 2791 | } |
2768 | - if ( m_manager.Playing && first ) { | |
2769 | - m_draw_start_index[selected - 1] = j; | |
2770 | - first = false; | |
2771 | - } | |
2772 | - if ( y + 2 * AppManager.EditorConfig.PxTrackHeight < 0 || y > height ) { | |
2773 | - continue; | |
2774 | - } | |
2775 | - Color id_fill; | |
2776 | - if ( m_manager.SelectedEvent.Count > 0 ) { | |
2777 | - bool found = m_manager.SelectedEvent.ContainsKey( dobj.InternalID ); | |
2778 | - if ( found ) { | |
2779 | - id_fill = AppManager.HilightColor; | |
2780 | - } else { | |
2781 | - id_fill = Color.FromArgb( 181, 220, 86 ); | |
2782 | - } | |
2783 | - } else { | |
2784 | - id_fill = Color.FromArgb( 181, 220, 86 ); | |
2785 | - } | |
2786 | - g.FillRectangle( | |
2787 | - new SolidBrush( id_fill ), | |
2788 | - new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2789 | - Font lyric_font = dobj.SymbolProtected ? s_font_bold : s_font_entry; | |
2790 | - if ( dobj.Overwrapped ) { | |
2791 | - g.DrawRectangle( s_pen_125_123_124, | |
2792 | - new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2793 | - if ( show_lyrics ) { | |
2794 | - g.DrawString( dobj.Text, | |
2795 | - lyric_font, | |
2796 | - s_brs_147_147_147, | |
2797 | - new PointF( x + 1, y + 1 ) ); | |
2798 | - } | |
2799 | - } else { | |
2800 | - g.DrawRectangle( s_pen_125_123_124, | |
2801 | - new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2802 | - if ( show_lyrics ) { | |
2803 | - g.DrawString( dobj.Text, | |
2804 | - lyric_font, | |
2805 | - Brushes.Black, | |
2806 | - new PointF( x + 1, y + 1 ) ); | |
2807 | - } | |
2808 | - if ( show_exp_line && lyric_width > 21 ) { | |
2809 | - #region 表情線 | |
2810 | - DrawAccentLine( g, new Point( x, y + AppManager.EditorConfig.PxTrackHeight + 1 ), dobj.Accent ); | |
2811 | - int vibrato_start = x + lyric_width; | |
2812 | - int vibrato_end = x; | |
2813 | - if ( dobj.pxVibratoDelay <= lyric_width ) { | |
2814 | - int vibrato_delay = dobj.pxVibratoDelay; | |
2815 | - int vibrato_width = dobj.pxRectangle.Width - vibrato_delay; | |
2816 | - vibrato_start = x + vibrato_delay; | |
2817 | - vibrato_end = x + vibrato_delay + vibrato_width; | |
2818 | - if ( vibrato_start - x < 21 ) { | |
2819 | - vibrato_start = x + 21; | |
2792 | +#endif | |
2793 | + if ( selected - 1 < m_draw_objects.Count ) { | |
2794 | + for ( int j = j_start; j < m_draw_objects[selected - 1].Count; j++ ) { | |
2795 | + DrawObject dobj = m_draw_objects[selected - 1][j]; | |
2796 | + int x = dobj.pxRectangle.X - start_draw_x; | |
2797 | + y = dobj.pxRectangle.Y - start_draw_y; | |
2798 | + int lyric_width = dobj.pxRectangle.Width; | |
2799 | + if ( x + lyric_width < 0 ) { | |
2800 | + continue; | |
2801 | + } else if ( width < x ) { | |
2802 | + break; | |
2803 | + } | |
2804 | + if ( m_manager.Playing && first ) { | |
2805 | + m_draw_start_index[selected - 1] = j; | |
2806 | + first = false; | |
2807 | + } | |
2808 | + if ( y + 2 * AppManager.EditorConfig.PxTrackHeight < 0 || y > height ) { | |
2809 | + continue; | |
2810 | + } | |
2811 | + Color id_fill; | |
2812 | + if ( m_manager.SelectedEvent.Count > 0 ) { | |
2813 | + bool found = m_manager.SelectedEvent.ContainsKey( dobj.InternalID ); | |
2814 | + if ( found ) { | |
2815 | + id_fill = AppManager.HilightColor; | |
2816 | + } else { | |
2817 | + id_fill = Color.FromArgb( 181, 220, 86 ); | |
2820 | 2818 | } |
2819 | + } else { | |
2820 | + id_fill = Color.FromArgb( 181, 220, 86 ); | |
2821 | 2821 | } |
2822 | - g.DrawLine( s_pen_051_051_000, | |
2823 | - new Point( x + 21, y + AppManager.EditorConfig.PxTrackHeight + 7 ), | |
2824 | - new Point( vibrato_start, y + AppManager.EditorConfig.PxTrackHeight + 7 ) ); | |
2825 | - if ( dobj.pxVibratoDelay <= lyric_width ) { | |
2826 | - int next_draw = vibrato_start; | |
2827 | - if ( vibrato_start < vibrato_end ) { | |
2828 | - DrawVibratoLine( g, | |
2829 | - new Point( vibrato_start, y + AppManager.EditorConfig.PxTrackHeight + 1 ), | |
2830 | - vibrato_end - vibrato_start ); | |
2822 | + g.FillRectangle( | |
2823 | + new SolidBrush( id_fill ), | |
2824 | + new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2825 | + Font lyric_font = dobj.SymbolProtected ? s_font_bold : s_font_entry; | |
2826 | + if ( dobj.Overwrapped ) { | |
2827 | + g.DrawRectangle( s_pen_125_123_124, | |
2828 | + new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2829 | + if ( show_lyrics ) { | |
2830 | + g.DrawString( dobj.Text, | |
2831 | + lyric_font, | |
2832 | + s_brs_147_147_147, | |
2833 | + new PointF( x + 1, y + 1 ) ); | |
2831 | 2834 | } |
2832 | - #endregion | |
2835 | + } else { | |
2836 | + g.DrawRectangle( s_pen_125_123_124, | |
2837 | + new Rectangle( x, y + 1, lyric_width, AppManager.EditorConfig.PxTrackHeight - 1 ) ); | |
2838 | + if ( show_lyrics ) { | |
2839 | + g.DrawString( dobj.Text, | |
2840 | + lyric_font, | |
2841 | + Brushes.Black, | |
2842 | + new PointF( x + 1, y + 1 ) ); | |
2843 | + } | |
2844 | + if ( show_exp_line && lyric_width > 21 ) { | |
2845 | + #region 表情線 | |
2846 | + DrawAccentLine( g, new Point( x, y + AppManager.EditorConfig.PxTrackHeight + 1 ), dobj.Accent ); | |
2847 | + int vibrato_start = x + lyric_width; | |
2848 | + int vibrato_end = x; | |
2849 | + if ( dobj.pxVibratoDelay <= lyric_width ) { | |
2850 | + int vibrato_delay = dobj.pxVibratoDelay; | |
2851 | + int vibrato_width = dobj.pxRectangle.Width - vibrato_delay; | |
2852 | + vibrato_start = x + vibrato_delay; | |
2853 | + vibrato_end = x + vibrato_delay + vibrato_width; | |
2854 | + if ( vibrato_start - x < 21 ) { | |
2855 | + vibrato_start = x + 21; | |
2856 | + } | |
2857 | + } | |
2858 | + g.DrawLine( s_pen_051_051_000, | |
2859 | + new Point( x + 21, y + AppManager.EditorConfig.PxTrackHeight + 7 ), | |
2860 | + new Point( vibrato_start, y + AppManager.EditorConfig.PxTrackHeight + 7 ) ); | |
2861 | + if ( dobj.pxVibratoDelay <= lyric_width ) { | |
2862 | + int next_draw = vibrato_start; | |
2863 | + if ( vibrato_start < vibrato_end ) { | |
2864 | + DrawVibratoLine( g, | |
2865 | + new Point( vibrato_start, y + AppManager.EditorConfig.PxTrackHeight + 1 ), | |
2866 | + vibrato_end - vibrato_start ); | |
2867 | + } | |
2868 | + #endregion | |
2869 | + } | |
2870 | + } | |
2833 | 2871 | } |
2834 | 2872 | } |
2835 | 2873 | } |
2836 | - | |
2837 | 2874 | } |
2838 | 2875 | } |
2839 | 2876 |
@@ -87,6 +87,7 @@ | ||
87 | 87 | this.menuJobConnect = new System.Windows.Forms.ToolStripMenuItem(); |
88 | 88 | this.menuJobLyric = new System.Windows.Forms.ToolStripMenuItem(); |
89 | 89 | this.menuJobRewire = new System.Windows.Forms.ToolStripMenuItem(); |
90 | + this.menuJobRealTime = new System.Windows.Forms.ToolStripMenuItem(); | |
90 | 91 | this.menuJobReloadVsti = new System.Windows.Forms.ToolStripMenuItem(); |
91 | 92 | this.menuTrack = new System.Windows.Forms.ToolStripMenuItem(); |
92 | 93 | this.menuTrackOn = new System.Windows.Forms.ToolStripMenuItem(); |
@@ -316,7 +317,6 @@ | ||
316 | 317 | this.stripBtnStartMarker = new System.Windows.Forms.ToolStripButton(); |
317 | 318 | this.stripBtnEndMarker = new System.Windows.Forms.ToolStripButton(); |
318 | 319 | this.openUstDialog = new System.Windows.Forms.OpenFileDialog(); |
319 | - this.menuJobRealTime = new System.Windows.Forms.ToolStripMenuItem(); | |
320 | 320 | this.menuStripMain.SuspendLayout(); |
321 | 321 | this.cMenuPiano.SuspendLayout(); |
322 | 322 | this.cMenuTrackTab.SuspendLayout(); |
@@ -762,6 +762,14 @@ | ||
762 | 762 | this.menuJobRewire.Size = new System.Drawing.Size( 227, 22 ); |
763 | 763 | this.menuJobRewire.Text = "ReWireホストからテンポを取得(&T)"; |
764 | 764 | // |
765 | + // menuJobRealTime | |
766 | + // | |
767 | + this.menuJobRealTime.Name = "menuJobRealTime"; | |
768 | + this.menuJobRealTime.ShortcutKeys = System.Windows.Forms.Keys.F5; | |
769 | + this.menuJobRealTime.Size = new System.Drawing.Size( 227, 22 ); | |
770 | + this.menuJobRealTime.Text = "Start Realtime Input"; | |
771 | + this.menuJobRealTime.Click += new System.EventHandler( this.menuJobRealTime_Click ); | |
772 | + // | |
765 | 773 | // menuJobReloadVsti |
766 | 774 | // |
767 | 775 | this.menuJobReloadVsti.Name = "menuJobReloadVsti"; |
@@ -951,7 +959,7 @@ | ||
951 | 959 | // menuSettingGameControlerSetting |
952 | 960 | // |
953 | 961 | this.menuSettingGameControlerSetting.Name = "menuSettingGameControlerSetting"; |
954 | - this.menuSettingGameControlerSetting.Size = new System.Drawing.Size( 152, 22 ); | |
962 | + this.menuSettingGameControlerSetting.Size = new System.Drawing.Size( 121, 22 ); | |
955 | 963 | this.menuSettingGameControlerSetting.Text = "Setting(&S)"; |
956 | 964 | this.menuSettingGameControlerSetting.Click += new System.EventHandler( this.menuSettingGameControlerSetting_Click ); |
957 | 965 | // |
@@ -958,7 +966,7 @@ | ||
958 | 966 | // menuSettingGameControlerReload |
959 | 967 | // |
960 | 968 | this.menuSettingGameControlerReload.Name = "menuSettingGameControlerReload"; |
961 | - this.menuSettingGameControlerReload.Size = new System.Drawing.Size( 152, 22 ); | |
969 | + this.menuSettingGameControlerReload.Size = new System.Drawing.Size( 121, 22 ); | |
962 | 970 | this.menuSettingGameControlerReload.Text = "Reload(&R)"; |
963 | 971 | this.menuSettingGameControlerReload.Click += new System.EventHandler( this.menuSettingGameControlerReload_Click ); |
964 | 972 | // |
@@ -2301,7 +2309,6 @@ | ||
2301 | 2309 | // |
2302 | 2310 | // stripLblGameCtrlMode |
2303 | 2311 | // |
2304 | - this.stripLblGameCtrlMode.AutoToolTip = true; | |
2305 | 2312 | this.stripLblGameCtrlMode.Image = global::Boare.Cadencii.Properties.Resources.slash; |
2306 | 2313 | this.stripLblGameCtrlMode.Name = "stripLblGameCtrlMode"; |
2307 | 2314 | this.stripLblGameCtrlMode.Size = new System.Drawing.Size( 65, 18 ); |
@@ -2315,9 +2322,11 @@ | ||
2315 | 2322 | // |
2316 | 2323 | // stripLblMidiIn |
2317 | 2324 | // |
2325 | + this.stripLblMidiIn.Image = global::Boare.Cadencii.Properties.Resources.slash; | |
2318 | 2326 | this.stripLblMidiIn.Name = "stripLblMidiIn"; |
2319 | - this.stripLblMidiIn.Size = new System.Drawing.Size( 49, 18 ); | |
2327 | + this.stripLblMidiIn.Size = new System.Drawing.Size( 65, 18 ); | |
2320 | 2328 | this.stripLblMidiIn.Text = "Disabled"; |
2329 | + this.stripLblMidiIn.ToolTipText = "Midi In Device"; | |
2321 | 2330 | // |
2322 | 2331 | // toolStripSeparator11 |
2323 | 2332 | // |
@@ -2767,14 +2776,6 @@ | ||
2767 | 2776 | // |
2768 | 2777 | this.openUstDialog.Filter = "UTAU Project File(*.ust)|*.ust|All Files(*.*)|*.*"; |
2769 | 2778 | // |
2770 | - // menuJobRealTime | |
2771 | - // | |
2772 | - this.menuJobRealTime.Name = "menuJobRealTime"; | |
2773 | - this.menuJobRealTime.ShortcutKeys = System.Windows.Forms.Keys.F5; | |
2774 | - this.menuJobRealTime.Size = new System.Drawing.Size( 227, 22 ); | |
2775 | - this.menuJobRealTime.Text = "Start Realtime Input"; | |
2776 | - this.menuJobRealTime.Click += new System.EventHandler( this.menuJobRealTime_Click ); | |
2777 | - // | |
2778 | 2779 | // FormMain |
2779 | 2780 | // |
2780 | 2781 | this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); |
@@ -798,6 +798,9 @@ | ||
798 | 798 | } |
799 | 799 | VSTiProxy.FirstBufferWritten -= vstidrv_FirstBufferWritten; |
800 | 800 | m_manager.FirstBufferWritten = false; |
801 | + if ( m_midi_in != null ) { | |
802 | + m_midi_in.Stop(); | |
803 | + } | |
801 | 804 | } |
802 | 805 | |
803 | 806 | private void m_manager_PreviewStarted( object sender, EventArgs e ) { |
@@ -992,6 +995,9 @@ | ||
992 | 995 | Common.DebugWriteLine( " m_config.VsqFile.TotalClocks=" + m_manager.VsqFile.TotalClocks ); |
993 | 996 | Common.DebugWriteLine( " total seconds=" + m_manager.VsqFile.SecFromClock( (int)m_manager.VsqFile.TotalClocks ) ); |
994 | 997 | #endif |
998 | + if ( m_midi_in != null ) { | |
999 | + m_midi_in.Start(); | |
1000 | + } | |
995 | 1001 | timer.Enabled = true; |
996 | 1002 | } |
997 | 1003 |
@@ -2448,6 +2454,9 @@ | ||
2448 | 2454 | } |
2449 | 2455 | AppManager.EditorConfig.WindowMaximized = (this.WindowState == FormWindowState.Maximized); |
2450 | 2456 | AppManager.SaveConfig(); |
2457 | + if ( m_midi_in != null ) { | |
2458 | + m_midi_in.Dispose(); | |
2459 | + } | |
2451 | 2460 | e.Cancel = false; |
2452 | 2461 | } |
2453 | 2462 |
@@ -5283,8 +5292,8 @@ | ||
5283 | 5292 | float play_time = VSTiProxy.GetPlayTime(); |
5284 | 5293 | float now = (float)(play_time + m_direct_play_shift); |
5285 | 5294 | #if DEBUG |
5286 | - Common.DebugWriteLine( "timer_Tick" ); | |
5287 | - Common.DebugWriteLine( " play_time=" + play_time ); | |
5295 | + //Common.DebugWriteLine( "timer_Tick" ); | |
5296 | + //Common.DebugWriteLine( " play_time=" + play_time ); | |
5288 | 5297 | #endif |
5289 | 5298 | if ( (play_time < 0.0 || m_preview_ending_time < now) && m_manager.EditMode != EditMode.Realtime ) { |
5290 | 5299 | m_manager.Playing = false; |
@@ -1,35 +0,0 @@ | ||
1 | -#ifndef __UtauEvent_h__ | |
2 | -#define __UtauEvent_h__ | |
3 | - | |
4 | -#include <string> | |
5 | -#include <vector> | |
6 | -#include <sstream> | |
7 | -using namespace std; | |
8 | - | |
9 | -struct UtauEvent{ | |
10 | -public: | |
11 | - int saTime; | |
12 | - int msLength; | |
13 | - int msDelay; | |
14 | - int Note; | |
15 | - float Tempo; | |
16 | - | |
17 | - UtauEvent(){ | |
18 | - } | |
19 | - | |
20 | - string GetLyric(){ | |
21 | - ostringstream os; | |
22 | - for( int i = 0; i < m_lyric.size(); i++ ){ | |
23 | - os << m_lyric[i]; | |
24 | - } | |
25 | - return os.str(); | |
26 | - }; | |
27 | - | |
28 | - void PushBack( char c ){ | |
29 | - m_lyric.push_back( c ); | |
30 | - }; | |
31 | -private: | |
32 | - vector<char> m_lyric; | |
33 | -}; | |
34 | - | |
35 | -#endif |
@@ -1,26 +0,0 @@ | ||
1 | -#ifndef __VsqNrpn_h__ | |
2 | -#define __VsqNrpn_h__ | |
3 | - | |
4 | -struct VsqNrpn { | |
5 | - int saTime; | |
6 | - unsigned int Nrpn; | |
7 | - unsigned char DataMsb; | |
8 | - unsigned char DataLsb; | |
9 | - VsqNrpn *Next; | |
10 | - | |
11 | - VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb ){ | |
12 | - saTime = sample_time; | |
13 | - Nrpn = nrpn; | |
14 | - DataMsb = data_msb; | |
15 | - Next = 0; | |
16 | - } | |
17 | - | |
18 | - VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb, unsigned char data_lsb ){ | |
19 | - saTime = sample_time; | |
20 | - Nrpn = nrpn; | |
21 | - DataMsb = data_msb; | |
22 | - DataLsb = data_lsb; | |
23 | - Next = 0; | |
24 | - } | |
25 | -}; | |
26 | -#endif // __VsqNrpn_h__ |
@@ -53,6 +53,7 @@ | ||
53 | 53 | |
54 | 54 | } // extern "C" |
55 | 55 | |
56 | +/* removed by kbinani 11 Apr., 2009 | |
56 | 57 | //------------------------------------------------------------------------ |
57 | 58 | #if WIN32 |
58 | 59 | #include <windows.h> |
@@ -66,3 +67,4 @@ | ||
66 | 67 | } |
67 | 68 | } // extern "C" |
68 | 69 | #endif |
70 | +*/ |
@@ -293,5 +293,6 @@ | ||
293 | 293 | case VCP_VOICE_CHANGE_PARAMETER: |
294 | 294 | return false; |
295 | 295 | } |
296 | + return false; | |
296 | 297 | } |
297 | 298 | #endif |
@@ -1,8 +1,129 @@ | ||
1 | 1 | #include "utauvsti.h" |
2 | 2 | |
3 | -int g_num_programs; | |
4 | -int g_num_params; | |
3 | +//----------------------------------------------------------------------------------------------- | |
4 | +// Platform Dependent | |
5 | +#ifdef WIN32 | |
6 | +#include <windows.h> | |
7 | +#include <shlwapi.h> | |
8 | +#pragma comment(lib, "shlwapi.lib") | |
5 | 9 | |
10 | +void* hInstance; | |
11 | + | |
12 | +extern "C" { | |
13 | + BOOL WINAPI DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved ){ | |
14 | + hInstance = hInst; | |
15 | + return 1; | |
16 | + } | |
17 | +} // extern "C" | |
18 | + | |
19 | +string get_filename_without_extension( string path ){ | |
20 | + if( path.size() <= 0 ){ | |
21 | + return ""; | |
22 | + } | |
23 | + string::size_type pos_dot = path.rfind( "." ); | |
24 | + string::size_type pos_bslash = path.rfind( "\\" ); | |
25 | + if( pos_dot < pos_bslash ){ | |
26 | + return path.substr( pos_bslash + 1 ); | |
27 | + }else{ | |
28 | + return path.substr( pos_bslash + 1, pos_dot - pos_bslash - 1 ); | |
29 | + } | |
30 | +} | |
31 | + | |
32 | +string get_directory_name( string path ){ | |
33 | + if( path.size() <= 0 ){ | |
34 | + return ""; | |
35 | + } | |
36 | + string::size_type pos_bslash = path.rfind( "\\" ); | |
37 | + return path.substr( 0, pos_bslash ); | |
38 | +} | |
39 | + | |
40 | +bool path_file_exists( string path ){ | |
41 | + BOOL ret = PathFileExistsA( path.c_str() ); | |
42 | + if( ret == FALSE ){ | |
43 | + return false; | |
44 | + }else{ | |
45 | + return true; | |
46 | + } | |
47 | +} | |
48 | + | |
49 | +bool path_directory_exists( string path ){ | |
50 | + BOOL ret = PathIsDirectoryA( path.c_str() ); | |
51 | + if( ret == FALSE ){ | |
52 | + return false; | |
53 | + }else{ | |
54 | + return true; | |
55 | + } | |
56 | +} | |
57 | + | |
58 | +void create_directory( string path ){ | |
59 | + if( !PathIsDirectoryA( path.c_str() ) ){ | |
60 | + CreateDirectoryA( path.c_str(), NULL ); | |
61 | + } | |
62 | +} | |
63 | + | |
64 | +string get_temp_path(){ | |
65 | + char buf[_MAX_PATH] = ""; | |
66 | + GetTempPathA( _MAX_PATH, buf ); | |
67 | + char buf2[_MAX_PATH] = ""; | |
68 | + GetLongPathNameA( buf, buf2, _MAX_PATH );//win95では使えない | |
69 | + return string( buf2 ); | |
70 | +} | |
71 | + | |
72 | +string get_dll_path(){ | |
73 | + char module_name[_MAX_PATH] = ""; | |
74 | + if( 0 != GetModuleFileNameA( (HMODULE)hInstance, module_name, _MAX_PATH ) ){ | |
75 | + return string( module_name ); | |
76 | + }else{ | |
77 | + return ""; | |
78 | + } | |
79 | +} | |
80 | + | |
81 | +string path_combine( string path1, string path2 ){ | |
82 | + if( path1.size() <= 0 ){ | |
83 | + return path2; | |
84 | + }else if ( path2.size() <= 0 ){ | |
85 | + return path1; | |
86 | + } | |
87 | + string s1, s2; | |
88 | + if( path1[path1.size() - 1] == '\\' ){ | |
89 | + s1 = path1.substr( 0, path1.size() - 1 ); | |
90 | + }else{ | |
91 | + s1 = path1; | |
92 | + } | |
93 | + if( path2[0] == '\\' ){ | |
94 | + s2 = path2; | |
95 | + }else{ | |
96 | + s2 = "\\" + path2; | |
97 | + } | |
98 | + return s1 + s2; | |
99 | +} | |
100 | + | |
101 | +void create_process( string filename, string argument, string working_directory ){ | |
102 | + g_logger << "create_process" << endl; | |
103 | + g_logger << " filename=" << filename << endl; | |
104 | + g_logger << " argument=" << argument << endl; | |
105 | + g_logger << " working_directory=" << working_directory << endl; | |
106 | + PROCESS_INFORMATION pi; | |
107 | + STARTUPINFOA si; | |
108 | + | |
109 | + ZeroMemory( &si, sizeof( si ) ); | |
110 | + si.cb = sizeof( si ); | |
111 | + | |
112 | + string narg = filename + " " + argument; | |
113 | + CreateProcessA( NULL, (LPSTR)narg.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi ); | |
114 | + CloseHandle( pi.hThread ); | |
115 | + WaitForSingleObject( pi.hProcess, INFINITE ); | |
116 | + CloseHandle( pi.hProcess ); | |
117 | +} | |
118 | +#else | |
119 | +#pragma error | |
120 | +#endif | |
121 | + | |
122 | +//----------------------------------------------------------------------------------------------- | |
123 | +// Platform Independent | |
124 | +int g_num_programs; | |
125 | +int g_num_params; | |
126 | + | |
6 | 127 | AudioEffect* createEffectInstance( audioMasterCallback audioMaster ){ |
7 | 128 | return new utauvsti( audioMaster ); |
8 | 129 | } |
@@ -12,7 +133,69 @@ | ||
12 | 133 | g_logger.open( "utauvsti.log", ios::out | ios::app ); |
13 | 134 | g_logger << "--------------------------------------------------------------------------" << std::endl; |
14 | 135 | #endif |
15 | - m_current_sample = 0; | |
136 | + m_singers.clear(); | |
137 | + m_dll_path = get_dll_path(); | |
138 | + string path = get_directory_name( m_dll_path ); | |
139 | + string dll = get_filename_without_extension( m_dll_path ); | |
140 | + string config = path_combine( path, dll + ".conf" ); | |
141 | + | |
142 | +#ifdef _DEBUG | |
143 | + g_logger << "path=" << path << endl; | |
144 | + g_logger << "dll=" << dll << endl; | |
145 | + g_logger << "config=" << config << endl; | |
146 | +#endif | |
147 | + | |
148 | + const int buf_len = 260; | |
149 | + char buf[buf_len]; | |
150 | + ifstream ifs( config.c_str(), ios::in ); | |
151 | + | |
152 | + ifs.getline( buf, buf_len ); | |
153 | + stringstream iss( buf ); | |
154 | + int config_file_version; | |
155 | + iss >> config_file_version; | |
156 | + | |
157 | + ifs.getline( buf, buf_len ); | |
158 | + m_resampler = buf; | |
159 | + | |
160 | + ifs.getline( buf, buf_len ); | |
161 | + m_wavtool = buf; | |
162 | + | |
163 | + ifs.getline( buf, buf_len ); | |
164 | + iss.clear(); | |
165 | + iss.str( buf ); | |
166 | + int num_singer = 0; | |
167 | + iss >> num_singer; | |
168 | +#ifdef _DEBUG | |
169 | + g_logger << "num_singer=" << num_singer << endl; | |
170 | +#endif | |
171 | + for( int i = 0; i < num_singer; i++ ){ | |
172 | + ifs.getline( buf, buf_len ); | |
173 | + m_singers.push_back( string( buf ) ); | |
174 | + } | |
175 | + | |
176 | + ifs.close(); | |
177 | + | |
178 | + m_current_singer = 0; | |
179 | + m_dict_singer = -1; | |
180 | + m_last_rendered = -1; | |
181 | + m_temp_dir = path_combine( get_temp_path(), "utauvsti" ); | |
182 | + if( !path_directory_exists( m_temp_dir ) ){ | |
183 | + create_directory( m_temp_dir ); | |
184 | + } | |
185 | + string tmpwav = path_combine( m_temp_dir, "result.wav" ); | |
186 | + if( path_file_exists( tmpwav ) ){ | |
187 | + remove( tmpwav.c_str() ); | |
188 | + } | |
189 | +#ifdef _DEBUG | |
190 | + g_logger << "m_dll_path=" << m_dll_path << endl; | |
191 | + g_logger << "m_resampler=" << m_resampler << endl; | |
192 | + g_logger << "m_wavtool=" << m_wavtool << endl; | |
193 | + g_logger << "num_singer=" << m_singers.size() << endl; | |
194 | + for( int i = 0; i < m_singers.size(); i++ ){ | |
195 | + g_logger << " " << m_singers[i] << endl; | |
196 | + } | |
197 | + g_logger << "m_temp_dir=" << m_temp_dir << endl; | |
198 | +#endif | |
16 | 199 | } |
17 | 200 | |
18 | 201 | utauvsti::~utauvsti(){ |
@@ -31,9 +214,9 @@ | ||
31 | 214 | #ifdef _DEBUG |
32 | 215 | g_logger << "dispatcher; effMainsChanged" << endl; |
33 | 216 | #endif |
34 | - m_current_sample = 0; | |
35 | 217 | m_events.clear(); |
36 | - m_tempo_table.clear(); | |
218 | + m_processed_sample = 0; | |
219 | + m_last_rendered = -1; | |
37 | 220 | break; |
38 | 221 | case effSetBlockSize: |
39 | 222 | #ifdef _DEBUG |
@@ -43,7 +226,7 @@ | ||
43 | 226 | break; |
44 | 227 | case effProcessEvents: |
45 | 228 | #ifdef _DEBUG |
46 | - g_logger << "dispatcher; effProcessEvents" << endl; | |
229 | + //g_logger << "dispatcher; effProcessEvents" << endl; | |
47 | 230 | #endif |
48 | 231 | VstEvents *incoming = (VstEvents*)ptr; |
49 | 232 | vector<VsqNrpn> nrpns; |
@@ -53,27 +236,16 @@ | ||
53 | 236 | unsigned char data_msb = 0x0; |
54 | 237 | unsigned char data_lsb = 0x0; |
55 | 238 | |
56 | - int base_sample = m_current_sample + incoming->events[0]->deltaFrames; | |
57 | - int first_sample = incoming->events[0]->deltaFrames; | |
239 | + int base_sample = m_processed_sample; | |
240 | + int last_lsb_sample = base_sample; //最後のnrpn lsbの発生時刻を表すサンプル数 | |
58 | 241 | |
59 | 242 | // VstEventsに入っているデータをVsqNrpnに変換 |
60 | - int last_sample = base_sample; | |
61 | 243 | for( int i = 0; i < incoming->numEvents; i++ ){ |
62 | 244 | if( incoming->events[i]->type != kVstMidiType ){ |
63 | 245 | continue; |
64 | 246 | } |
65 | 247 | VstMidiEvent *vme = (VstMidiEvent*)incoming->events[i]; |
66 | -#ifdef _DEBUG | |
67 | - g_logger << " "; | |
68 | - for( int k = 1; k < 3; k++ ){ | |
69 | - g_logger << "0x" << hex << (int)vme->midiData[k] << dec << "\t"; | |
70 | - } | |
71 | - g_logger << "deltaFrames=" << vme->deltaFrames; | |
72 | - g_logger << endl; | |
73 | -#endif | |
74 | 248 | unsigned int pn = 0x0; |
75 | - int this_sample = base_sample + (vme->deltaFrames - first_sample); | |
76 | - last_sample = this_sample; | |
77 | 249 | if( vme->midiData[0] == (char)0xb0 ){ |
78 | 250 | // NRPNの場合 |
79 | 251 | switch( vme->midiData[1] ){ |
@@ -83,6 +255,7 @@ | ||
83 | 255 | break; |
84 | 256 | case 0x62: |
85 | 257 | addr_lsb = vme->midiData[2]; |
258 | + last_lsb_sample = base_sample + vme->deltaFrames; | |
86 | 259 | break; |
87 | 260 | case 0x06: |
88 | 261 | data_msb = vme->midiData[2]; |
@@ -89,41 +262,29 @@ | ||
89 | 262 | pn = addr_msb << 8 | addr_lsb; |
90 | 263 | if( !is_require_data_lsb( pn ) ){ |
91 | 264 | // nrpnがdata lsbを使用しない場合,datalsbの出現を待たずにイベントを登録 |
92 | - nrpns.push_back( VsqNrpn( this_sample, pn, data_msb ) ); | |
265 | + nrpns.push_back( VsqNrpn( last_lsb_sample, pn, data_msb, m_processed_sample ) ); | |
93 | 266 | } |
94 | 267 | break; |
95 | 268 | case 0x26: |
96 | - data_lsb = incoming->events[i]->data[2]; | |
269 | + data_lsb = vme->midiData[2]; | |
97 | 270 | pn = addr_msb << 8 | addr_lsb; |
98 | - nrpns.push_back( VsqNrpn( this_sample, pn, data_msb ) ); | |
271 | + nrpns.push_back( VsqNrpn( last_lsb_sample, pn, data_msb, data_lsb, m_processed_sample ) ); | |
99 | 272 | break; |
100 | 273 | } |
101 | - }else if( vme->midiData[0] == (char)0xff ){ | |
102 | - // テンポ変更イベントの場合 | |
103 | - if( vme->midiData[1] == 0x51 && vme->midiData[2] == 0x03 ){ | |
104 | - int tempo = (vme->midiData[3] << 16) | (vme->midiData[4] << 8) | vme->midiData[5]; | |
105 | - m_tempo_table.push_back( TempoTableEntry( this_sample, tempo, 0.0 ) ); | |
106 | - } | |
107 | 274 | } |
108 | 275 | } |
109 | 276 | |
110 | - // m_tempo_table[*]のTimeの部分を更新する | |
111 | - update_tempo_table(); | |
112 | - | |
113 | - if( incoming->numEvents > 0 ){ | |
114 | - m_current_sample += (last_sample - base_sample); | |
115 | - } | |
116 | - | |
117 | 277 | // 歌詞情報を再構成 |
118 | 278 | int note_number = 60; |
119 | 279 | int ms_delay = 0; |
120 | 280 | int ms_duration = 0; |
121 | - vector<char> lyric; | |
281 | + UtauEvent work; | |
122 | 282 | for( int i = 0; i < nrpns.size(); i++ ){ |
123 | 283 | if( nrpns[i].Nrpn == CVM_NM_NOTE_NUMBER ){ |
124 | 284 | note_number = nrpns[i].DataMsb; |
125 | 285 | }else if( CVM_NM_PHONETIC_SYMBOL1 <= nrpns[i].Nrpn && nrpns[i].Nrpn < 0x504f ) { |
126 | - lyric.push_back( nrpns[i].DataMsb ); | |
286 | + int index = (int)nrpns[i].Nrpn - (int)CVM_NM_PHONETIC_SYMBOL1; | |
287 | + work.set_lyric( index, (char)nrpns[i].DataMsb ); | |
127 | 288 | }else if( nrpns[i].Nrpn == CVM_NM_NOTE_DURATION ){ |
128 | 289 | ms_duration = nrpns[i].DataMsb << 7 | nrpns[i].DataLsb; |
129 | 290 | }else if( nrpns[i].Nrpn == CVM_NM_DELAY ){ |
@@ -130,21 +291,32 @@ | ||
130 | 291 | ms_delay = nrpns[i].DataMsb << 7 | nrpns[i].DataLsb; |
131 | 292 | }else if( nrpns[i].Nrpn == CVM_NM_NOTE_MESSAGE_CONTINUATION && nrpns[i].DataMsb == 0x7f ){ |
132 | 293 | UtauEvent ue; |
133 | - ue.saTime = nrpns[i].saTime; | |
294 | + ue.saTime = nrpns[i].saTime + (int)(ms_delay / 1000.0 * m_sample_rate); | |
295 | + ue.saLength = ms_duration / 1000.0 * m_sample_rate; | |
134 | 296 | ue.Note = note_number; |
135 | - ue.msDelay = ms_delay; | |
136 | - ue.msLength = ms_duration; | |
137 | - for( int i = 0; i < lyric.size(); i++ ){ | |
138 | - ue.PushBack( lyric[i] ); | |
297 | + int len = m_events.size(); | |
298 | + int sa_end = 0; | |
299 | + if( len > 0 ){ | |
300 | + sa_end = m_events[len - 1].saTime + m_events[len - 1].saLength; | |
139 | 301 | } |
302 | + if( ue.saTime > sa_end ){ | |
303 | + // 休符の挿入 | |
304 | + UtauEvent ue2; | |
305 | + ue2.set_lyric( "R" ); | |
306 | + ue2.Note = 60; | |
307 | + ue2.saLength = ue.saTime - sa_end; | |
308 | + ue2.saTime = sa_end; | |
309 | + m_events.push_back( ue2 ); | |
310 | + } | |
311 | + ue.set_lyric( work.get_lyric() ); | |
312 | + work.set_lyric( "" ); | |
140 | 313 | m_events.push_back( ue ); |
141 | - lyric.clear(); | |
142 | 314 | } |
143 | 315 | } |
144 | 316 | |
145 | - for( int i = 0; i < m_events.size(); i++ ){ | |
146 | - g_logger << " time(sec)=" << ((m_events[i].saTime / (double)m_sample_rate) + m_events[i].msDelay / 1000.0) << " note=" << m_events[i].Note << " lyric=" << m_events[i].GetLyric() << endl; | |
147 | - } | |
317 | + /*for( int i = 0; i < m_events.size(); i++ ){ | |
318 | + g_logger << (m_events[i].saTime / (double)m_sample_rate) << "\t" << ((m_events[i].saTime + m_events[i].saLength) / (double)m_sample_rate) << "\t" << m_events[i].Note << "\t" << m_events[i].get_lyric() << endl; | |
319 | + }*/ | |
148 | 320 | |
149 | 321 | break; |
150 | 322 | } |
@@ -151,30 +323,120 @@ | ||
151 | 323 | return 0; |
152 | 324 | } |
153 | 325 | |
154 | -void utauvsti::update_tempo_table(){ | |
155 | - /*if( m_tempo_table.size() == 0 ){ | |
156 | - m_tempo_table.push_back( TempoTableEntry( 0, k_base_tempo, 0.0 ) ); | |
326 | +void utauvsti::processReplacing( float** inputs, float** outputs, VstInt32 sampleFrames ){ | |
327 | + const string filebase = "result.wav"; | |
328 | + const double sec_per_clock = k_tempo * 1e-6 / 480.0; | |
329 | + const string dumy_tempo = "120.00"; | |
330 | + | |
331 | + if( m_current_singer != m_dict_singer ){ | |
332 | + load_singer_config(); | |
157 | 333 | } |
158 | - //TempoTable.Sort(); | |
159 | - if ( m_tempo_table[0].saTime != 0 ) { | |
160 | - m_tempo_table[0].Time = (double)k_base_tempo * (double)m_tempo_table[0].Clock / (k_clock_per_quoter * 1000000.0); | |
161 | - } else { | |
162 | - m_tempo_table[0].Time = 0.0; | |
334 | + if( m_processed_sample == 0 ){ | |
335 | + string tmp = path_combine( m_temp_dir, filebase + ".whd" ); | |
336 | + if( path_file_exists( tmp ) ){ | |
337 | + remove( tmp.c_str() ); | |
338 | + } | |
339 | + tmp = path_combine( m_temp_dir, filebase + ".dat" ); | |
340 | + if( path_file_exists( tmp ) ){ | |
341 | + remove( tmp.c_str() ); | |
342 | + } | |
163 | 343 | } |
164 | - double prev_time = m_tempo_table[0].Time; | |
165 | - int prev_clock = m_tempo_table[0].Clock; | |
166 | - int prev_tempo = m_tempo_table[0].Tempo; | |
167 | - double inv_tpq_sec = 1.0 / (k_clock_per_quoter * 1000000.0); | |
168 | - for ( int i = 1; i < m_tempo_table.size(); i++ ) { | |
169 | - m_tempo_table[i].Time = prev_time + (double)prev_tempo * (double)(m_tempo_table[i].Clock - prev_clock) * inv_tpq_sec; | |
170 | - prev_time = m_tempo_table[i].Time; | |
171 | - prev_tempo = m_tempo_table[i].Tempo; | |
172 | - prev_clock = m_tempo_table[i].Clock; | |
173 | - }*/ | |
344 | + int from = m_processed_sample + 1; | |
345 | + int to = m_processed_sample + sampleFrames; | |
346 | + int rendered_last = 0; | |
347 | + if( 0 <= m_last_rendered && m_last_rendered < m_events.size() ){ | |
348 | + rendered_last = m_events[m_last_rendered].saTime + m_events[m_last_rendered].saLength; | |
349 | + } | |
350 | + if( to > rendered_last ){ | |
351 | + //要求された部分のレンダリングが行われていない場合 | |
352 | + string singer = m_singers[m_current_singer]; | |
353 | + while( to > rendered_last && m_last_rendered + 1 < m_events.size() ){ | |
354 | + m_last_rendered++; | |
355 | + // resampler呼び出し | |
356 | + ostringstream oss( "" ); | |
357 | + oss << m_last_rendered << ".wav"; | |
358 | + string filename = oss.str(); | |
359 | + string note = note_string_from_note_number( m_events[m_last_rendered].Note ); | |
360 | + OtoArgs oa; | |
361 | + bool mode_r = false; | |
362 | + string lyric = m_events[m_last_rendered].get_lyric(); | |
363 | + if( lyric == "R" ){ | |
364 | + mode_r = true; | |
365 | + } | |
366 | + if( !mode_r ){ | |
367 | + lyric = "あ"; | |
368 | + if( m_singer_config.find( lyric ) != m_singer_config.end() ){ | |
369 | + oa = m_singer_config[lyric]; | |
370 | + } | |
371 | + } | |
372 | + oss.str( "" ); | |
373 | + oss << (int)(m_events[m_last_rendered].saLength / (double)m_sample_rate * 1000.0); | |
374 | + string millisec = oss.str(); | |
375 | + oss.str( "" ); | |
376 | + oss << "\"" << path_combine( singer, lyric + ".wav" ) << "\" \"" << path_combine( m_temp_dir, filename ) + "\" \"" << note << "\" 100 L " << oa.A2 << " " + millisec << " " << oa.A3 << " " << oa.A4 << " 100 100"; | |
377 | + string arg = oss.str(); | |
378 | + create_process( "\"" + m_resampler + "\"", arg, m_temp_dir ); | |
379 | + | |
380 | + // wavtool呼び出し | |
381 | + int dumy_clocks = (int)(m_events[m_last_rendered].saLength / m_sample_rate / sec_per_clock); | |
382 | + oss.str( "" ); | |
383 | + oss << "\"" << path_combine( m_temp_dir, filebase ) << "\" "; | |
384 | + if( mode_r ){ | |
385 | + oss << "\"" << path_combine( singer, "R.wav" ) << "\""; | |
386 | + }else{ | |
387 | + oss << "\"" << path_combine( m_temp_dir, filename ) << "\""; | |
388 | + } | |
389 | + oss << " 0 " << dumy_clocks << "@" << dumy_tempo << "+" << oa.A5; | |
390 | + if( mode_r ){ | |
391 | + oss << " 0 0"; | |
392 | + }else{ | |
393 | + oss << " 0 5 35 0 100 100 " << oa.A6; | |
394 | + } | |
395 | + arg = oss.str(); | |
396 | + create_process( "\"" + m_wavtool + "\"", arg, m_temp_dir ); | |
397 | + rendered_last = m_events[m_last_rendered].saTime + m_events[m_last_rendered].saLength; | |
398 | + } | |
399 | + } | |
400 | + m_processed_sample += sampleFrames; | |
174 | 401 | } |
175 | 402 | |
176 | -void utauvsti::processReplacing( float** inputs, float** outputs, VstInt32 sampleFrames ){ | |
177 | - | |
403 | +void utauvsti::load_singer_config(){ | |
404 | + m_singer_config.clear(); | |
405 | + string path = m_singers[m_current_singer]; // c:\ ... \voice\oto | |
406 | + string dir = get_directory_name( path ); // c:\ ... \voice | |
407 | + string name = get_filename_without_extension( path ); // oto | |
408 | + string config_name = path_combine( path, name + ".ini" ); | |
409 | +#ifdef _DEBUG | |
410 | + g_logger << "config_name=" << config_name << endl; | |
411 | +#endif | |
412 | + const int buflen = 256; | |
413 | + char buf[buflen]; | |
414 | + ifstream ifs( config_name.c_str(), ios::in ); | |
415 | + while( ifs.peek() >= 0 ){ | |
416 | + ifs.getline( buf, buflen ); | |
417 | + string line( buf ); | |
418 | + string::size_type pos_eq = line.rfind( "=" ); | |
419 | + string lyric = line.substr( 0, pos_eq ); | |
420 | + line = line.substr( pos_eq + 1 ); | |
421 | + OtoArgs oa; | |
422 | + oa.A1 = 0; | |
423 | + string::size_type pos0 = -1; | |
424 | + int vals[6]; | |
425 | + for( int i = 0; i < 6; i++ ){ | |
426 | + string::size_type pos1 = line.find( ",", pos0 + 1 ); | |
427 | + string spl = line.substr( pos0 + 1, pos1 - (pos0 + 1) + 1 ); | |
428 | + stringstream ss( spl ); | |
429 | + ss >> vals[i]; | |
430 | + pos0 = pos1; | |
431 | + } | |
432 | + oa.A2 = vals[1]; | |
433 | + oa.A3 = vals[2]; | |
434 | + oa.A4 = vals[3]; | |
435 | + oa.A5 = vals[4]; | |
436 | + oa.A6 = vals[5]; | |
437 | + m_singer_config.insert( map<string, OtoArgs>::value_type( lyric, oa ) ); | |
438 | + } | |
439 | + m_dict_singer = m_current_singer; | |
178 | 440 | } |
179 | 441 | |
180 | 442 | bool utauvsti::getEffectName( char* name ){ |
@@ -3,9 +3,11 @@ | ||
3 | 3 | #include "audioeffectx.h" |
4 | 4 | #include <fstream> |
5 | 5 | #include <string> |
6 | +#include <algorithm> | |
7 | +#include <sstream> | |
8 | +#include <vector> | |
9 | +#include <map> | |
6 | 10 | #include "NRPN.h" |
7 | -#include "VsqNrpn.h" | |
8 | -#include "UtauEvent.h" | |
9 | 11 | |
10 | 12 | using namespace std; |
11 | 13 |
@@ -13,18 +15,74 @@ | ||
13 | 15 | VstIntPtr AudioMaster( AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt ); |
14 | 16 | std::ofstream g_logger; |
15 | 17 | |
16 | -struct TempoTableEntry{ | |
18 | +string get_filename_without_extension( string path ); | |
19 | + | |
20 | +struct UtauEvent{ | |
21 | +public: | |
17 | 22 | int saTime; |
18 | - double Time; | |
19 | - int Tempo; | |
23 | + int saLength; | |
24 | + int Note; | |
20 | 25 | |
21 | - TempoTableEntry( int sample_time, int tempo, double time ){ | |
22 | - saTime = sample_time; | |
23 | - Tempo = tempo; | |
24 | - Time = time; | |
26 | + UtauEvent(){ | |
27 | + for( int i = 0; i < LYRIC_LEN; i++ ){ | |
28 | + m_lyric[i] = '\0'; | |
29 | + } | |
25 | 30 | }; |
31 | + | |
32 | + string get_lyric(){ | |
33 | + ostringstream os; | |
34 | + for( int i = 0; i < LYRIC_LEN; i++ ){ | |
35 | + if( m_lyric[i] != '\0' ){ | |
36 | + os << m_lyric[i]; | |
37 | + }else{ | |
38 | + break; | |
39 | + } | |
40 | + } | |
41 | + return os.str(); | |
42 | + }; | |
43 | + | |
44 | + void set_lyric( string s ){ | |
45 | + for( int i = 0; i < LYRIC_LEN; i++ ){ | |
46 | + m_lyric[i] = '\0'; | |
47 | + } | |
48 | + for( int i = 0; i < s.length() && i < LYRIC_LEN; i++ ){ | |
49 | + set_lyric( i, s[i] ); | |
50 | + } | |
51 | + }; | |
52 | + | |
53 | + void set_lyric( int index, char c ){ | |
54 | + if( 0 <= index && index < LYRIC_LEN ){ | |
55 | + m_lyric[index] = c; | |
56 | + } | |
57 | + }; | |
58 | +private: | |
59 | + static const int LYRIC_LEN = 60; | |
60 | + char m_lyric[LYRIC_LEN]; | |
26 | 61 | }; |
27 | 62 | |
63 | + | |
64 | +// 原音設定の引数. | |
65 | +struct OtoArgs{ | |
66 | + /// 第1引数.空文字なので使わない | |
67 | + int A1; | |
68 | + int A2; | |
69 | + int A3; | |
70 | + int A4; | |
71 | + int A5; | |
72 | + int A6; | |
73 | + OtoArgs(){ | |
74 | + A1 = 0; | |
75 | + A2 = 0; | |
76 | + A3 = 0; | |
77 | + A4 = 0; | |
78 | + A5 = 0; | |
79 | + A6 = 0; | |
80 | + }; | |
81 | +}; | |
82 | + | |
83 | +//------------------------------------------------------------------------------------------------------- | |
84 | +//** utauvsti * | |
85 | +//------------------------------------------------------------------------------------------------------- | |
28 | 86 | class utauvsti : public AudioEffectX { |
29 | 87 | public: |
30 | 88 | utauvsti( audioMasterCallback audioMaster ); |
@@ -32,9 +90,9 @@ | ||
32 | 90 | |
33 | 91 | //----------------------------------------------------------------------------------------------- |
34 | 92 | // AEffect |
35 | - virtual VstIntPtr dispatcher (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt); | |
93 | + virtual VstIntPtr dispatcher( VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt ); | |
36 | 94 | |
37 | - virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames); | |
95 | + virtual void processReplacing( float** inputs, float** outputs, VstInt32 sampleFrames ); | |
38 | 96 | |
39 | 97 | virtual bool getEffectName( char* name ); |
40 | 98 | virtual bool getVendorString( char* text ); |
@@ -314,11 +372,17 @@ | ||
314 | 372 | } |
315 | 373 | return ""; |
316 | 374 | }; |
317 | - void update_tempo_table(); | |
375 | + static string note_string_from_note_number( int note_number ){ | |
376 | + int odd = note_number % 12; | |
377 | + string list[12] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; | |
378 | + string head = list[odd]; | |
379 | + ostringstream oss( "" ); | |
380 | + oss << head << (note_number / 12 - 1); | |
381 | + return oss.str(); | |
382 | + }; | |
318 | 383 | private: |
319 | 384 | static const int k_version = 1; |
320 | - static const int k_base_tempo = 500000; | |
321 | - static const int k_clock_per_quoter = 480; | |
385 | + static const int k_tempo = 500000; | |
322 | 386 | // サンプリングレート |
323 | 387 | float m_sample_rate; |
324 | 388 | // ブロックサイズ.使わない? |
@@ -325,7 +389,67 @@ | ||
325 | 389 | int m_block_size; |
326 | 390 | // effProcessEventにて取り出したイベント情報 |
327 | 391 | vector<UtauEvent> m_events; |
328 | - int m_current_sample; | |
329 | - vector<TempoTableEntry> m_tempo_table; | |
392 | + // processReplacingによって処理されたサンプル数 | |
330 | 393 | int m_processed_sample; |
394 | + // 自分自身のファイル名 | |
395 | + string m_dll_path; | |
396 | + // resampler.exeのパス | |
397 | + string m_resampler; | |
398 | + // wavtool.exeのパス | |
399 | + string m_wavtool; | |
400 | + // 音源フォルダのリスト | |
401 | + vector<string> m_singers; | |
402 | + // 現在している音源の、原音設定 | |
403 | + map<string, OtoArgs> m_singer_config; | |
404 | + // m_singer_configに入っている音源のインデックス | |
405 | + int m_dict_singer; | |
406 | + // 現在使用している音源のインデックス(プログラムチェンジで変更) | |
407 | + int m_current_singer; | |
408 | + // 最後にレンダリングされたm_eventsのインデックス | |
409 | + int m_last_rendered; | |
410 | + // 一時ファイルを保存するフォルダ | |
411 | + string m_temp_dir; | |
412 | + | |
413 | + void load_singer_config(); | |
331 | 414 | }; |
415 | + | |
416 | +struct VsqNrpn { | |
417 | + int saTime; | |
418 | + int debug_saProcessed; | |
419 | + unsigned int Nrpn; | |
420 | + unsigned char DataMsb; | |
421 | + unsigned char DataLsb; | |
422 | + VsqNrpn *Next; | |
423 | + | |
424 | + VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb, int processed ){ | |
425 | + saTime = sample_time; | |
426 | + Nrpn = nrpn; | |
427 | + DataMsb = data_msb; | |
428 | + Next = 0; | |
429 | + debug_saProcessed = processed; | |
430 | + } | |
431 | + | |
432 | + VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb, unsigned char data_lsb, int processed ){ | |
433 | + saTime = sample_time; | |
434 | + Nrpn = nrpn; | |
435 | + DataMsb = data_msb; | |
436 | + DataLsb = data_lsb; | |
437 | + Next = 0; | |
438 | + debug_saProcessed = processed; | |
439 | + } | |
440 | + | |
441 | + VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb ){ | |
442 | + saTime = sample_time; | |
443 | + Nrpn = nrpn; | |
444 | + DataMsb = data_msb; | |
445 | + Next = 0; | |
446 | + } | |
447 | + | |
448 | + VsqNrpn( int sample_time, unsigned int nrpn, unsigned char data_msb, unsigned char data_lsb ){ | |
449 | + saTime = sample_time; | |
450 | + Nrpn = nrpn; | |
451 | + DataMsb = data_msb; | |
452 | + DataLsb = data_lsb; | |
453 | + Next = 0; | |
454 | + } | |
455 | +}; |
@@ -27,29 +27,17 @@ | ||
27 | 27 | #ifndef __stdafx_h__ |
28 | 28 | #define __stdafx_h__ |
29 | 29 | |
30 | -#ifdef __cplusplus_cli | |
31 | -#define __PFX_INTERFACE__ virtual | |
32 | -#define __PFX_MEMBER__ | |
33 | -#else | |
34 | -#define __PFX_INTERFACE__ static | |
35 | -#define __PFX_MEMBER__ static | |
36 | -#endif | |
30 | +typedef void (*WaveIncomingCallback)( double *L, double *R, int length ); | |
31 | +typedef void (*FirstBufferWrittenCallback)(); | |
32 | +typedef void (*RenderingFinishedCallback)(); | |
37 | 33 | |
38 | 34 | namespace Boare{ namespace Cadencii{ |
39 | 35 | |
40 | -#ifdef __cplusplus_cli | |
41 | - ref class dlldebug{ | |
42 | - public: | |
43 | - static System::IO::StreamWriter ^logger; | |
44 | - static void push_log( System::String ^s ); | |
45 | - }; | |
46 | -#else | |
47 | 36 | class dlldebug{ |
48 | 37 | public: |
49 | 38 | static std::ofstream logger; |
50 | 39 | static void awake(); |
51 | 40 | }; |
52 | -#endif | |
53 | 41 | } } |
54 | 42 | #endif // __stdafx_h__ |
55 | 43 |
@@ -20,7 +20,6 @@ | ||
20 | 20 | static int g_block_size; // 波形バッファのサイズ。 |
21 | 21 | static int g_sample_rate; // サンプリングレート。VOCALOID2 VSTiは限られたサンプリングレートしか受け付けない。たいてい44100Hzにする |
22 | 22 | |
23 | -#ifndef __cplusplus_cli | |
24 | 23 | extern "C"{ |
25 | 24 | void vstidrv_setFirstBufferWrittenCallback( FirstBufferWrittenCallback proc ){ |
26 | 25 | #if TEST |
@@ -125,7 +124,6 @@ | ||
125 | 124 | return 110; |
126 | 125 | } |
127 | 126 | } |
128 | -#endif | |
129 | 127 | |
130 | 128 | namespace Boare{ namespace Cadencii{ |
131 | 129 |
@@ -145,9 +143,9 @@ | ||
145 | 143 | bool vstidrv::g_cancelRequired; |
146 | 144 | double vstidrv::g_progress; |
147 | 145 | string vstidrv::s_plugin_version; |
148 | - FirstBufferWrittenCallback vstidrv::s_first_buffer_written_callback; | |
149 | - WaveIncomingCallback vstidrv::s_wave_incoming_callback; | |
150 | - RenderingFinishedCallback vstidrv::s_rendering_finished_callback; | |
146 | + FirstBufferWrittenCallback vstidrv::s_first_buffer_written_callback = 0; | |
147 | + WaveIncomingCallback vstidrv::s_wave_incoming_callback = 0; | |
148 | + RenderingFinishedCallback vstidrv::s_rendering_finished_callback = 0; | |
151 | 149 | |
152 | 150 | void vstidrv::SetFirstBufferWrittenCallback( FirstBufferWrittenCallback proc ){ |
153 | 151 | #ifdef TEST |
@@ -189,6 +187,9 @@ | ||
189 | 187 | int vstidrv::free_events( MIDI_EVENT* pEvent ){ |
190 | 188 | MIDI_EVENT* pEventTmp; |
191 | 189 | while( pEvent ){ |
190 | +#ifdef TEST | |
191 | + | |
192 | +#endif | |
192 | 193 | pEventTmp = pEvent->pNext; |
193 | 194 | delete pEvent->pMidiEvent; |
194 | 195 | delete pEvent; |
@@ -351,7 +352,7 @@ | ||
351 | 352 | Sleep( 250 ); |
352 | 353 | #ifdef TEST |
353 | 354 | int hm = (int)dll_handle; |
354 | - std::cout << " dll_handle=0x" << std::hex << hm << std::endl; | |
355 | + std::cout << " dll_handle=0x" << hex << hm << dec << std::endl; | |
355 | 356 | dlldebug::logger << " dll_handle=0x" << hex << hm << dec << endl; |
356 | 357 | #endif |
357 | 358 | g_dllHandle = dll_handle; |
@@ -360,7 +361,7 @@ | ||
360 | 361 | Sleep( 250 ); |
361 | 362 | #ifdef TEST |
362 | 363 | int addr = (int)main; |
363 | - dlldebug::logger << " (int)main=0x" << std::hex << addr << std::endl; | |
364 | + dlldebug::logger << " (int)main=0x" << hex << addr << dec << endl; | |
364 | 365 | #endif |
365 | 366 | if( !main ){ |
366 | 367 | return false; |
@@ -375,7 +376,7 @@ | ||
375 | 376 | } |
376 | 377 | #ifdef TEST |
377 | 378 | addr = (int)s_aeffect; |
378 | - dlldebug::logger << " (int)s_aeffect=0x" << std::hex << addr << std::endl; | |
379 | + dlldebug::logger << " (int)s_aeffect=0x" << hex << addr << dec << endl; | |
379 | 380 | #endif |
380 | 381 | if( !s_aeffect ){ |
381 | 382 | return false; |
@@ -495,7 +496,7 @@ | ||
495 | 496 | ){ |
496 | 497 | #ifdef TEST |
497 | 498 | dlldebug::awake(); |
498 | - dlldebug::logger << "vstidrv::StartRendering" << endl; | |
499 | + dlldebug::logger << "vstidrv::StartRendering ..." << endl; | |
499 | 500 | #endif |
500 | 501 | g_cancelRequired = false; |
501 | 502 | g_progress = 0.0; |
@@ -567,6 +568,9 @@ | ||
567 | 568 | waveplay::set_error_samples( error_samples ); |
568 | 569 | |
569 | 570 | MIDI_EVENT* pWork = s_track_events[1]; |
571 | +#ifdef TEST | |
572 | + dlldebug::logger << "(!dwDelay && pWork)=" << ((!dwDelay && pWork) ? "True" : "False") << endl; | |
573 | +#endif | |
570 | 574 | while( !dwDelay && pWork ){ |
571 | 575 | // Delayの取得 |
572 | 576 | if( (pWork->pMidiEvent[0] & 0xf0) == 0xb0 ){ |
@@ -585,8 +589,8 @@ | ||
585 | 589 | data_lsb = pWork->pMidiEvent[2]; |
586 | 590 | if( addr_msb == 0x50 && addr_lsb == 0x01 ){ |
587 | 591 | delay = data_msb << 7 | data_lsb; |
588 | -#ifdef _DEBUG | |
589 | - std::cout << "delay=" << delay << std::endl; | |
592 | +#ifdef TEST | |
593 | + dlldebug::logger << "delay=" << delay << std::endl; | |
590 | 594 | #endif |
591 | 595 | dwDelay = (unsigned long)(delay * (double)g_sample_rate / 1000.0); |
592 | 596 | } |
@@ -596,21 +600,45 @@ | ||
596 | 600 | pWork = pWork->pNext; |
597 | 601 | } |
598 | 602 | |
599 | - while( -1 ){ | |
603 | +#ifdef TEST | |
604 | + dlldebug::logger << "enter while(-1); dwNow=" << dwNow << flush << endl; | |
605 | +#endif | |
606 | + while( true ){ | |
607 | +#ifdef TEST | |
608 | + dlldebug::logger << "in the loop of while(-1)" << flush << endl; | |
609 | +#endif | |
600 | 610 | if ( g_cancelRequired ) { |
611 | +#ifdef TEST | |
612 | + dlldebug::logger << "cancel required" << flush << endl; | |
613 | +#endif | |
601 | 614 | delete [] left_ch; |
602 | 615 | delete [] right_ch; |
616 | +#ifdef TEST | |
617 | + dlldebug::logger << "calling free_events..."; | |
618 | +#endif | |
603 | 619 | free_events( lpEvents ); |
620 | +#ifdef TEST | |
621 | + dlldebug::logger << "done" << flush << endl; | |
622 | +#endif | |
604 | 623 | exit_start_rendering(); |
624 | +#ifdef TEST | |
625 | + dlldebug::logger << "...exit" << flush << endl; | |
626 | +#endif | |
605 | 627 | return FALSE; |
606 | 628 | } |
607 | 629 | #ifdef _DEBUG |
608 | - std::cout << "-----------------------------------------------------------------------" << std::endl; | |
630 | + //std::cout << "-----------------------------------------------------------------------" << std::endl; | |
609 | 631 | #endif |
610 | 632 | MIDI_EVENT* pProcessEvent = current; |
611 | 633 | int nEvents = 0; |
612 | 634 | |
635 | +#ifdef TEST | |
636 | + dlldebug::logger << "(current->clock==dwNow)=" << (current->clock == dwNow ? "True" : "False") << flush << endl; | |
637 | +#endif | |
613 | 638 | while( current->clock == dwNow ){ |
639 | +#ifdef TEST | |
640 | + dlldebug::logger << "(current->clock==dwNow)=" << (current->clock == dwNow ? "True" : "False") << flush << endl; | |
641 | +#endif | |
614 | 642 | // durationを取得 |
615 | 643 | if( (current->pMidiEvent[0] & 0xf0) == 0xb0 ){ |
616 | 644 | switch( current->pMidiEvent[1] ){ |
@@ -630,7 +658,7 @@ | ||
630 | 658 | if( addr_msb == 0x50 && addr_lsb == 0x4 ){ |
631 | 659 | duration = data_msb << 7 | data_lsb; |
632 | 660 | #ifdef _DEBUG |
633 | - std::cout << "duration=" << duration<< std::endl; | |
661 | + std::cout << "duration=" << duration<< flush << std::endl; | |
634 | 662 | #endif |
635 | 663 | } |
636 | 664 | break; |
@@ -648,18 +676,18 @@ | ||
648 | 676 | break; |
649 | 677 | } |
650 | 678 | |
651 | -#ifdef _DEBUG | |
652 | - std::cout << "nEvents=" << nEvents << std::endl; | |
679 | +#ifdef TEST | |
680 | + dlldebug::logger << "nEvents=" << nEvents << std::endl << flush; | |
653 | 681 | #endif |
654 | 682 | double msNow = totalMilliSec_from_timeCode( dwNow ); |
655 | 683 | double msPrev = totalMilliSec_from_timeCode( dwPrev ); |
656 | 684 | double dt = msNow - msPrev; |
657 | 685 | dwDelta = (unsigned long)(dt * g_sample_rate / 1000.0); |
658 | -#ifdef _DEBUG | |
659 | - std::cout << "dwNow=" << dwNow << std::endl; | |
660 | - std::cout << "dwPrev=" << dwPrev << std::endl; | |
661 | - std::cout << "dt=" << dt << std::endl; | |
662 | - std::cout << "dwDelta=" << dwDelta << std::endl; | |
686 | +#ifdef TEST | |
687 | + dlldebug::logger << "dwNow=" << dwNow << std::endl << flush; | |
688 | + dlldebug::logger << "dwPrev=" << dwPrev << std::endl << flush; | |
689 | + dlldebug::logger << "dt=" << dt << std::endl << flush; | |
690 | + dlldebug::logger << "dwDelta=" << dwDelta << std::endl << flush; | |
663 | 691 | #endif |
664 | 692 | |
665 | 693 | VstEvents* pVSTEvents = (VstEvents*)malloc( sizeof(VstEvents) + nEvents * sizeof(VstEvent*) ); |
@@ -694,18 +722,41 @@ | ||
694 | 722 | } |
695 | 723 | pProcessEvent = pProcessEvent->pNext; |
696 | 724 | } |
725 | +#ifdef TEST | |
726 | + dlldebug::logger << "calling dispatcher(..effProcessEvents..)..." << flush; | |
727 | +#endif | |
697 | 728 | s_aeffect->dispatcher( s_aeffect, effProcessEvents, 0, 0, pVSTEvents, 0 ); |
729 | +#ifdef TEST | |
730 | + dlldebug::logger << "done" << endl << flush; | |
731 | +#endif | |
698 | 732 | |
699 | - while( dwDelta ){ | |
733 | + while( dwDelta > 0 ){ | |
734 | +#ifdef TEST | |
735 | + dlldebug::logger << "dwDelta=" << dwDelta << endl << flush; | |
736 | +#endif | |
700 | 737 | if ( g_cancelRequired ) { |
701 | 738 | delete [] left_ch; |
702 | 739 | delete [] right_ch; |
703 | 740 | free_events( lpEvents ); |
704 | 741 | exit_start_rendering(); |
742 | +#ifdef TEST | |
743 | + dlldebug::logger << "...exit" << endl << flush; | |
744 | +#endif | |
705 | 745 | return FALSE; |
706 | 746 | } |
707 | - unsigned long dwFrames = dwDelta > (unsigned long)g_sample_rate ? (unsigned long)g_sample_rate : dwDelta; | |
747 | + int dwFrames = dwDelta > (unsigned long)g_sample_rate ? g_sample_rate : (int)dwDelta; | |
748 | + int buf_frames = dwFrames; | |
749 | +#ifdef TEST | |
750 | + dlldebug::logger << "before dwFrames=" << dwFrames << endl << flush; | |
751 | + dlldebug::logger << "calling processReplacing..." << flush; | |
752 | +#endif | |
708 | 753 | s_aeffect->processReplacing( s_aeffect, NULL, out_buffer, dwFrames ); |
754 | +#ifdef TEST | |
755 | + dlldebug::logger << "done" << endl << flush; | |
756 | + dlldebug::logger << "after1 dwFrames=" << dwFrames << endl << flush; | |
757 | + dwFrames = buf_frames; | |
758 | + dlldebug::logger << "after2 dwFrames=" << dwFrames << endl << flush; | |
759 | +#endif | |
709 | 760 | |
710 | 761 | int iOffset = dwDelay - dwDeltaDelay; |
711 | 762 | if( iOffset > (int)dwFrames ){ |
@@ -714,9 +765,15 @@ | ||
714 | 765 | |
715 | 766 | if ( !iOffset ) { |
716 | 767 | if( direct_play_enabled ){ |
768 | +#ifdef TEST | |
769 | + dlldebug::logger << "calling waveplay::append..." << flush; | |
770 | +#endif | |
717 | 771 | waveplay::append( out_buffer, dwFrames, amplify_left, amplify_right ); |
772 | +#ifdef TEST | |
773 | + dlldebug::logger << "done" << endl << flush; | |
774 | +#endif | |
718 | 775 | } |
719 | - if( event_enabled ){ | |
776 | + if( event_enabled && s_wave_incoming_callback ){ | |
720 | 777 | double *send_data_l = new double[dwFrames]; |
721 | 778 | double *send_data_r = new double[dwFrames]; |
722 | 779 | for( int i = 0; i < (int)dwFrames; i++ ){ |
@@ -723,15 +780,37 @@ | ||
723 | 780 | send_data_l[i] = out_buffer[0][i] * amplify_left; |
724 | 781 | send_data_r[i] = out_buffer[1][i] * amplify_right; |
725 | 782 | } |
783 | +#ifdef TEST | |
784 | + dlldebug::logger << "calling s_wave_incoming_callback..." << flush; | |
785 | +#endif | |
726 | 786 | s_wave_incoming_callback( send_data_l, send_data_r, dwFrames ); |
787 | +#ifdef TEST | |
788 | + dlldebug::logger << "done" << endl << flush; | |
789 | +#endif | |
727 | 790 | } |
791 | +#ifdef TEST | |
792 | + dlldebug::logger << "before: total_processed=" << total_processed << endl << flush; | |
793 | +#endif | |
728 | 794 | total_processed += dwFrames; |
795 | +#ifdef TEST | |
796 | + dlldebug::logger << "after: total_processed=" << total_processed << endl << flush; | |
797 | +#endif | |
729 | 798 | } else { |
730 | 799 | dwDeltaDelay += iOffset; |
731 | 800 | } |
801 | +#ifdef TEST | |
802 | + dlldebug::logger << "dwFrames=" << dwFrames << endl << flush; | |
803 | + dlldebug::logger << "before: dwDelta=" << dwDelta << endl << flush; | |
804 | +#endif | |
732 | 805 | dwDelta -= dwFrames; |
806 | +#ifdef TEST | |
807 | + dlldebug::logger << "after: dwDelta=" << dwDelta << endl << flush; | |
808 | +#endif | |
733 | 809 | } |
734 | 810 | |
811 | +#ifdef TEST | |
812 | + dlldebug::logger << "free( pVSTEvents );" << endl << flush; | |
813 | +#endif | |
735 | 814 | free( pVSTEvents ); |
736 | 815 | |
737 | 816 | dwPrev = dwNow; |
@@ -739,12 +818,22 @@ | ||
739 | 818 | g_progress = total_processed / (double)total_samples * 100.0; |
740 | 819 | } |
741 | 820 | |
821 | +#ifdef TEST | |
822 | + dlldebug::logger << "process remainings" << endl << flush; | |
823 | +#endif | |
824 | + | |
742 | 825 | double msLast = totalMilliSec_from_timeCode( dwNow ); |
743 | 826 | dwDelta = (unsigned long)(g_sample_rate * ((double)duration + (double)delay) / 1000.0 + dwDeltaDelay); |
744 | 827 | while( dwDelta ){ |
828 | +#ifdef TEST | |
829 | + dlldebug::logger << "dwDelta=" << dwDelta << endl << flush; | |
830 | +#endif | |
745 | 831 | if ( g_cancelRequired ) { |
746 | 832 | free_events( lpEvents ); |
747 | 833 | exit_start_rendering(); |
834 | +#ifdef TEST | |
835 | + dlldebug::logger << "...exit" << endl << flush; | |
836 | +#endif | |
748 | 837 | return FALSE; |
749 | 838 | } |
750 | 839 | unsigned long dwFrames = dwDelta > (unsigned long)g_sample_rate ? (unsigned long)g_sample_rate : dwDelta; |
@@ -753,7 +842,7 @@ | ||
753 | 842 | if( direct_play_enabled ){ |
754 | 843 | waveplay::append( out_buffer, dwFrames, amplify_left, amplify_right ); |
755 | 844 | } |
756 | - if( event_enabled ){ | |
845 | + if( event_enabled && s_wave_incoming_callback ){ | |
757 | 846 | double *send_data_l = new double[dwFrames]; |
758 | 847 | double *send_data_r = new double[dwFrames]; |
759 | 848 | for( int i = 0; i < (int)dwFrames; i++ ){ |
@@ -770,7 +859,7 @@ | ||
770 | 859 | s_aeffect->dispatcher( s_aeffect, effMainsChanged, 0, 0, 0, 0 ); |
771 | 860 | |
772 | 861 | #ifdef TEST |
773 | - std::cout << "vstidrv::StartRendering; total_processed=" << total_processed << std::endl; | |
862 | + std::cout << "vstidrv::StartRendering; total_processed=" << total_processed << std::endl << flush; | |
774 | 863 | #endif |
775 | 864 | if( direct_play_enabled ){ |
776 | 865 | if( total_processed < max_wave_samples ){ |
@@ -789,6 +878,10 @@ | ||
789 | 878 | |
790 | 879 | free_events( lpEvents ); |
791 | 880 | |
881 | +#ifdef TEST | |
882 | + dlldebug::logger << "direct_play_enabled=" << (direct_play_enabled ? "True" : "False") << endl; | |
883 | + dlldebug::logger << "mode_infinite=" << (mode_infinite ? "True" : "False") << endl; | |
884 | +#endif | |
792 | 885 | if( direct_play_enabled ){ |
793 | 886 | if( mode_infinite ){ |
794 | 887 | while( !g_cancelRequired ){ |
@@ -795,7 +888,7 @@ | ||
795 | 888 | waveplay::append( out_buffer, g_block_size, 0.0, 0.0 ); |
796 | 889 | } |
797 | 890 | }else{ |
798 | - while( waveplay::is_alive() ); | |
891 | + while( waveplay::is_alive() ); | |
799 | 892 | } |
800 | 893 | } |
801 | 894 |
@@ -805,6 +898,9 @@ | ||
805 | 898 | if( s_rendering_finished_callback ){ |
806 | 899 | s_rendering_finished_callback(); |
807 | 900 | } |
901 | +#ifdef TEST | |
902 | + dlldebug::logger << "...exit" << endl; | |
903 | +#endif | |
808 | 904 | return TRUE; |
809 | 905 | } |
810 | 906 |
@@ -176,6 +176,7 @@ | ||
176 | 176 | #ifdef TEST |
177 | 177 | dlldebug::awake(); |
178 | 178 | dlldebug::logger << "append_cor *************************************************************" << endl; |
179 | + dlldebug::logger << " length=" << length << endl; | |
179 | 180 | #endif |
180 | 181 | s_playing = true; |
181 | 182 | int jmax = length; |
@@ -32,10 +32,7 @@ | ||
32 | 32 | void CALLBACK waveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ); |
33 | 33 | void first_buffer_written_callback(); |
34 | 34 | |
35 | -typedef void (*WaveIncomingCallback)( double *L, double *R, int length ); | |
36 | -typedef void (*FirstBufferWrittenCallback)(); | |
37 | -typedef void (*RenderingFinishedCallback)(); | |
38 | -extern "C"{ | |
35 | +extern "C" { | |
39 | 36 | void vstidrv_setFirstBufferWrittenCallback( FirstBufferWrittenCallback proc ); |
40 | 37 | void vstidrv_setWaveIncomingCallback( WaveIncomingCallback proc ); |
41 | 38 | void vstidrv_setRenderingFinishedCallback( RenderingFinishedCallback proc ); |
@@ -68,6 +65,9 @@ | ||
68 | 65 | |
69 | 66 | struct MIDI_EVENT{ |
70 | 67 | public: |
68 | + MIDI_EVENT(){ | |
69 | + pNext = 0; | |
70 | + }; | |
71 | 71 | unsigned int clock; |
72 | 72 | MIDI_EVENT *pNext; |
73 | 73 | unsigned int dwDataSize; |
@@ -79,95 +79,54 @@ | ||
79 | 79 | |
80 | 80 | class vstidrv{ |
81 | 81 | private: |
82 | - __PFX_MEMBER__ AEffect *s_aeffect; // 読込んだdllから作成したVOCALOID2の本体。VOCALOID2への操作はs_aeffect->dispatcherで行う | |
83 | - __PFX_MEMBER__ MIDI_EVENT **s_track_events; // 受信したmidiイベントのリスト。s_track_events[0]はvsqのマスタートラックのtempo情報のみを格納 | |
82 | + static AEffect *s_aeffect; // 読込んだdllから作成したVOCALOID2の本体。VOCALOID2への操作はs_aeffect->dispatcherで行う | |
83 | + static MIDI_EVENT **s_track_events; // 受信したmidiイベントのリスト。s_track_events[0]はvsqのマスタートラックのtempo情報のみを格納 | |
84 | 84 | // s_track_events[1]はレンダリングしたいトラックのmidiを格納。SendMidiで更新する |
85 | - __PFX_MEMBER__ HMODULE g_dllHandle; // 読込んだdllのハンドル | |
86 | - __PFX_MEMBER__ MIDI_EVENT *g_pEvents; // s_track_events[0]とs_track_events[1]を合成した物。SendMidiで、s_track_events[0]と | |
85 | + static HMODULE g_dllHandle; // 読込んだdllのハンドル | |
86 | + static MIDI_EVENT *g_pEvents; // s_track_events[0]とs_track_events[1]を合成した物。SendMidiで、s_track_events[0]と | |
87 | 87 | // s_track_events[1]の両方がそろった時点でmerge_eventsで合成する。 |
88 | - __PFX_MEMBER__ MIDI_EVENT *g_pCurrentEvent; // g_pEventsの中の、現在読込んでいるMIDI_EVENTへのポインタ | |
89 | - __PFX_MEMBER__ bool g_midiPrepared0; // s_track_events[0]のmidiイベントを受信済みかどうかを表すフラグ | |
90 | - __PFX_MEMBER__ bool g_midiPrepared1; // s_track_events[1]のmidiイベントを受信済みかどうかを表すフラグ | |
91 | - __PFX_MEMBER__ int g_tcCurrent; | |
92 | - __PFX_MEMBER__ int g_tcPrevious; | |
93 | - __PFX_MEMBER__ int g_saProcessed; | |
94 | - __PFX_MEMBER__ int g_saTotalSamples; | |
95 | - __PFX_MEMBER__ TempoInfo *g_tempoList; | |
96 | - __PFX_MEMBER__ int g_numTempoList; | |
97 | - __PFX_MEMBER__ bool g_cancelRequired; | |
98 | - __PFX_MEMBER__ double g_progress; | |
88 | + static MIDI_EVENT *g_pCurrentEvent; // g_pEventsの中の、現在読込んでいるMIDI_EVENTへのポインタ | |
89 | + static bool g_midiPrepared0; // s_track_events[0]のmidiイベントを受信済みかどうかを表すフラグ | |
90 | + static bool g_midiPrepared1; // s_track_events[1]のmidiイベントを受信済みかどうかを表すフラグ | |
91 | + static int g_tcCurrent; | |
92 | + static int g_tcPrevious; | |
93 | + static int g_saProcessed; | |
94 | + static int g_saTotalSamples; | |
95 | + static TempoInfo *g_tempoList; | |
96 | + static int g_numTempoList; | |
97 | + static bool g_cancelRequired; | |
98 | + static double g_progress; | |
99 | 99 | |
100 | -#ifdef __cplusplus_cli | |
101 | - String ^s_plugin_version; | |
102 | -#else | |
103 | 100 | static string s_plugin_version; |
104 | 101 | static WaveIncomingCallback s_wave_incoming_callback; |
105 | 102 | static RenderingFinishedCallback s_rendering_finished_callback; |
106 | -#endif | |
107 | 103 | |
108 | - __PFX_MEMBER__ int free_events( MIDI_EVENT* pEvent ); | |
109 | - __PFX_MEMBER__ MIDI_EVENT* merge_events( MIDI_EVENT* x0,MIDI_EVENT* y0 ); | |
110 | - __PFX_MEMBER__ MIDI_EVENT* copy_event( MIDI_EVENT* x ); | |
111 | - __PFX_MEMBER__ MIDI_EVENT* clone_event( MIDI_EVENT* pEvent ); | |
104 | + static int free_events( MIDI_EVENT* pEvent ); | |
105 | + static MIDI_EVENT* merge_events( MIDI_EVENT* x0,MIDI_EVENT* y0 ); | |
106 | + static MIDI_EVENT* copy_event( MIDI_EVENT* x ); | |
107 | + static MIDI_EVENT* clone_event( MIDI_EVENT* pEvent ); | |
112 | 108 | /// <summary> |
113 | 109 | /// 指定したタイムコードにおける,曲頭から測った時間を調べる |
114 | 110 | /// </summary> |
115 | - __PFX_MEMBER__ double totalMilliSec_from_timeCode( int timeCode ); | |
116 | - __PFX_MEMBER__ int ProcessEvents( int numEvents, VstEvent events[] ); | |
111 | + static double totalMilliSec_from_timeCode( int timeCode ); | |
112 | + static int ProcessEvents( int numEvents, VstEvent events[] ); | |
117 | 113 | |
118 | -#ifdef __cplusplus_cli | |
119 | - String ^GetVersion(); | |
120 | -#else | |
121 | 114 | static string GetVersion(); |
122 | -#endif | |
123 | - __PFX_MEMBER__ void exit_start_rendering(); | |
115 | + static void exit_start_rendering(); | |
124 | 116 | |
125 | -#ifdef __cplusplus_cli | |
126 | - FirstBufferWrittenEventHandler ^s_first_buffer_written_callback; | |
127 | -#else | |
128 | 117 | static FirstBufferWrittenCallback s_first_buffer_written_callback; |
129 | -#endif | |
130 | 118 | |
131 | 119 | public: |
132 | 120 | vstidrv(); |
133 | -#ifdef __cplusplus_cli | |
134 | - static vstidrv ^GetInstance(); | |
135 | -#endif | |
136 | - | |
137 | -#ifdef __cplusplus_cli | |
138 | - void Main( array<String ^> ^arg ); | |
139 | -#endif | |
140 | - | |
141 | -#if defined __cplusplus_cli | |
142 | - virtual event WaveIncomingEventHandler ^WaveIncoming; | |
143 | - virtual event RenderingFinishedEventHandler ^RenderingFinished; | |
144 | - virtual void SetFirstBufferWrittenCallback( FirstBufferWrittenEventHandler ^handler ); | |
145 | -#else | |
146 | 121 | static void SetFirstBufferWrittenCallback( FirstBufferWrittenCallback proc ); |
147 | 122 | static void SetWaveIncomingCallback( WaveIncomingCallback proc ); |
148 | 123 | static void SetRenderingFinishedCallback( RenderingFinishedCallback proc ); |
149 | -#endif | |
150 | 124 | |
151 | 125 | static void InvokeFirstBufferWrittenEvent(); |
152 | -#if defined __cplusplus_cli | |
153 | - virtual bool Init( array<System::Char> ^dll_path, int block_size, int sample_rate ); | |
154 | -#else | |
155 | 126 | static bool Init( char *dll_path, int block_size, int sample_rate ); |
156 | -#endif | |
157 | 127 | |
158 | - __PFX_INTERFACE__ int SendEvent( unsigned char *src, int *deltaFrames, int numEvents, int targetTrack ); | |
128 | + static int SendEvent( unsigned char *src, int *deltaFrames, int numEvents, int targetTrack ); | |
159 | 129 | |
160 | -#if defined __cplusplus_cli | |
161 | - virtual int StartRendering( | |
162 | - __int64 total_samples, | |
163 | - double amplify_left, | |
164 | - double amplify_right, | |
165 | - int error_samples, | |
166 | - bool event_enabled, | |
167 | - bool direct_play_enabled, | |
168 | - array<System::String ^> ^files, | |
169 | - double wave_read_offset_seconds ); | |
170 | -#else | |
171 | 130 | static int StartRendering( |
172 | 131 | __int64 total_samples, |
173 | 132 | double amplify_left, |
@@ -179,36 +138,27 @@ | ||
179 | 138 | int num_files, |
180 | 139 | double wave_read_offset_seconds, |
181 | 140 | bool mode_infinite ); |
182 | -#endif | |
183 | - __PFX_INTERFACE__ void AbortRendering(); | |
184 | - __PFX_INTERFACE__ double GetProgress(); | |
185 | - __PFX_INTERFACE__ float GetPlayTime(); | |
186 | - __PFX_INTERFACE__ void WaveOutReset(); | |
187 | - __PFX_INTERFACE__ void Terminate(); | |
141 | + static void AbortRendering(); | |
142 | + static double GetProgress(); | |
143 | + static float GetPlayTime(); | |
144 | + static void WaveOutReset(); | |
145 | + static void Terminate(); | |
188 | 146 | |
189 | 147 | // 初期化。戻り値は、接続されているゲームパッドの個数 |
190 | - __PFX_INTERFACE__ int JoyInit(); | |
148 | + static int JoyInit(); | |
191 | 149 | // 第index番目のゲームパッドが接続されているかどうかを調べる |
192 | - __PFX_INTERFACE__ bool JoyIsJoyAttatched( int index ); | |
150 | + static bool JoyIsJoyAttatched( int index ); | |
193 | 151 | // 第index番目のゲームパッドの状態を取得する。 |
194 | -#if defined __cplusplus_cli | |
195 | - virtual bool JoyGetStatus( | |
196 | - int index, | |
197 | - [System::Runtime::InteropServices::Out] array<Byte> ^%buttons, | |
198 | - int len, | |
199 | - [System::Runtime::InteropServices::Out] int %pov ); | |
200 | -#else | |
201 | 152 | static bool JoyGetStatus( |
202 | 153 | int index, |
203 | 154 | unsigned char *buttons, |
204 | 155 | int len, |
205 | 156 | int *pov ); |
206 | -#endif | |
207 | 157 | // 第index番目のゲームパッドが認識できるボタンの個数を取得する。 |
208 | - __PFX_INTERFACE__ int JoyGetNumButtons( int index ); | |
158 | + static int JoyGetNumButtons( int index ); | |
209 | 159 | // リセット。 |
210 | - __PFX_INTERFACE__ void JoyReset(); | |
211 | - __PFX_INTERFACE__ int JoyGetNumJoyDev(); | |
160 | + static void JoyReset(); | |
161 | + static int JoyGetNumJoyDev(); | |
212 | 162 | }; |
213 | 163 | |
214 | 164 | } } |
@@ -24,11 +24,7 @@ | ||
24 | 24 | public: |
25 | 25 | ~wavereader(); |
26 | 26 | wavereader(); |
27 | -#ifdef __cplusplus_cli | |
28 | - int open( wchar_t *file ); | |
29 | -#else | |
30 | 27 | int open( char *file ); |
31 | -#endif | |
32 | 28 | void read( __int64 start, __int64 length, float *left, float *right ); |
33 | 29 | void close(); |
34 | 30 | private: |
@@ -19,7 +19,6 @@ | ||
19 | 19 | using namespace std; |
20 | 20 | |
21 | 21 | // 最初のバッファが書き込まれたとき呼び出されるコールバック関数 |
22 | -typedef void (*FirstBufferWrittenCallback)(); | |
23 | 22 | |
24 | 23 | class waveplay{ |
25 | 24 | private: |
@@ -51,11 +50,7 @@ | ||
51 | 50 | static float *s_wave_buffer_l; |
52 | 51 | static float *s_wave_buffer_r; |
53 | 52 | static void mix( int processed_count, float amp_left, float amp_right ); |
54 | -#ifdef __cplusplus_cli | |
55 | - static System::String ^waveplay::util_get_errmsg( MMRESULT msg ); | |
56 | -#else | |
57 | 53 | static string waveplay::util_get_errmsg( MMRESULT msg ); |
58 | -#endif | |
59 | 54 | public: |
60 | 55 | /// 初期化関数 |
61 | 56 | static void init( int block_size, int sample_rate ); |
@@ -70,11 +65,7 @@ | ||
70 | 65 | static void reset(); |
71 | 66 | /// 再生のための準備を行う。この関数を呼び出した後は、バッファが再生開始されるまでget_play_timeの戻り値は0となる(負値にならない)。 |
72 | 67 | /// 戻り値は、filesに指定されたファイルの内、最も再生時間の長いwaveファイルの、合計サンプル数 |
73 | -#ifdef __cplusplus_cli | |
74 | - static int on_your_mark( array<System::String ^> ^files, __int64 wave_read_offset_samples ); | |
75 | -#else | |
76 | 68 | static int on_your_mark( char **files, int num_files, __int64 wave_read_offset_samples ); |
77 | -#endif | |
78 | 69 | static void set_error_samples( int error_samples ); |
79 | 70 | /// コールバック関数を設定する |
80 | 71 | static void set_first_buffer_written_callback( FirstBufferWrittenCallback proc ); |
@@ -244,7 +244,8 @@ | ||
244 | 244 | 500, |
245 | 245 | false, |
246 | 246 | new string[] { }, |
247 | - 0.0 ); | |
247 | + 0.0, | |
248 | + false ); | |
248 | 249 | } |
249 | 250 | |
250 | 251 | double max_volume_rendered = 0.0; |