git-svn-id: http://svn.sourceforge.jp/svnroot/lipsync@11 b1f601f4-4f45-0410-8980-aecacb008692
This commit is contained in:
		
							parent
							
								
									ea047ec460
								
							
						
					
					
						commit
						aa4ffe769a
					
				
							
								
								
									
										210
									
								
								trunk/Boare.Lib.AppUtil/CursorUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								trunk/Boare.Lib.AppUtil/CursorUtil.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,210 @@ | ||||
| #define RGB24 | ||||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Drawing; | ||||
| using System.IO; | ||||
| using System.Drawing.Imaging; | ||||
| 
 | ||||
| 
 | ||||
| using System; | ||||
| using System.Drawing; | ||||
| using System.Drawing.Imaging; | ||||
| using System.ComponentModel; | ||||
| using System.Windows.Forms; | ||||
| using System.IO; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Reflection; | ||||
| using bocoree; | ||||
| 
 | ||||
| namespace Boare.Lib.AppUtil { | ||||
| 
 | ||||
|     public static class CursorUtil { | ||||
|         public static void SaveAsIcon( Bitmap item, Stream stream, Color transp ) { | ||||
|             SaveCor( item, new Point( 0, 0 ), stream, 1, transp ); | ||||
|         } | ||||
| 
 | ||||
|         public static void SaveAsCursor( Bitmap item, Point hotspot, Stream stream, Color transp ) { | ||||
|             SaveCor( item, hotspot, stream, 2, transp ); | ||||
|         } | ||||
| 
 | ||||
|         private static void SaveCor( Bitmap item, Point hotspot, Stream stream, ushort type, Color transp ) { | ||||
|             IconFileHeader ifh = new IconFileHeader(); | ||||
|             ifh.icoReserved = 0x0; | ||||
|             ifh.icoResourceCount = 1; | ||||
|             ifh.icoResourceType = type; | ||||
|             ifh.Write( stream ); | ||||
|             IconInfoHeader iif = new IconInfoHeader(); | ||||
|             BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); | ||||
|             iif.Width = (byte)item.Width; | ||||
|             iif.Height = (byte)item.Height; | ||||
|             iif.ColorCount = 0; | ||||
|             iif.Reserved1 = 0; | ||||
|             iif.Reserved2 = (ushort)hotspot.X; | ||||
|             iif.Reserved3 = (ushort)hotspot.Y; | ||||
| #if RGB24 | ||||
|             int linesize = ((item.Width * 24 + 31) / 32) * 4; | ||||
| #else | ||||
|             int linesize = ((item.Width * 32 + 31) / 32) * 4; | ||||
| #endif | ||||
|             int linesize_mask = ((item.Width * 1 + 31) / 32) * 4; | ||||
|             int size = linesize * item.Height + linesize_mask * item.Height + 40; | ||||
| #if DEBUG | ||||
|             Console.WriteLine( "linesize=" + linesize ); | ||||
| #endif | ||||
|             iif.icoDIBSize = (uint)size; | ||||
|             iif.icoDIBOffset = 0x16; | ||||
|             iif.Write( stream ); | ||||
|             bih.biSize = 40; | ||||
|             bih.biWidth = item.Width; | ||||
| #if RGB24 | ||||
|             bih.biHeight = item.Height * 2; | ||||
| #else | ||||
|             bih.biHeight = item.Height * 2; | ||||
| #endif | ||||
|             bih.biPlanes = 1; | ||||
| #if RGB24 | ||||
|             bih.biBitCount = 24; | ||||
| #else | ||||
|             bih.biBitCount = 32; | ||||
| #endif | ||||
|             bih.biCompression = 0; | ||||
|             bih.biSizeImage = (uint)(linesize * item.Height); | ||||
|             bih.biXPelsPerMeter = 0;//            (int)(item.HorizontalResolution / 2.54e-2); | ||||
|             bih.biYPelsPerMeter = 0;//            (int)(item.VerticalResolution / 2.54e-2); | ||||
|             bih.biClrUsed = 0; | ||||
|             bih.biClrImportant = 0; | ||||
|             bih.Write( stream ); | ||||
|             for ( int y = item.Height - 1; y >= 0; y-- ) { | ||||
|                 int count = 0; | ||||
|                 for ( int x = 0; x < item.Width; x++ ) { | ||||
|                     Color c = item.GetPixel( x, y ); | ||||
|                     stream.WriteByte( (byte)c.B ); | ||||
|                     stream.WriteByte( (byte)c.G ); | ||||
|                     stream.WriteByte( (byte)c.R ); | ||||
| #if DEBUG | ||||
|                     if ( c.R != transp.R || c.G != transp.G || c.B != transp.B ) { | ||||
|                         Console.WriteLine( "color=" + c ); | ||||
|                     } | ||||
| #endif | ||||
| #if RGB24 | ||||
|                     count += 3; | ||||
| #else | ||||
|                     stream.WriteByte( (byte)c.A ); | ||||
|                     count += 4; | ||||
| #endif | ||||
|                 } | ||||
|                 for ( int i = count; i < linesize; i++ ) { | ||||
|                     stream.WriteByte( 0x0 ); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             for ( int y = item.Height - 1; y >= 0; y-- ) { | ||||
|                 int count = 0; | ||||
|                 byte v = 0x0; | ||||
|                 int tcount = 0; | ||||
|                 for ( int x = 0; x < item.Width; x++ ) { | ||||
|                     Color c = item.GetPixel( x, y ); | ||||
|                     byte tr = 0x0; | ||||
|                     if ( c.R == transp.R && c.G == transp.G && c.B == transp.B ){ | ||||
|                         tr = 0x1; | ||||
|                     } | ||||
|                     v = (byte)((byte)(v << 1) | (byte)(tr & 0x1)); | ||||
|                     tcount++; | ||||
|                     if ( tcount == 8 ) { | ||||
|                         stream.WriteByte( v ); | ||||
|                         count++; | ||||
|                         tcount = 0; | ||||
|                         v = 0x0; | ||||
|                     } | ||||
|                 } | ||||
|                 if ( 0 < tcount ) { | ||||
|                     v = (byte)(v << (9 - tcount)); | ||||
|                     stream.WriteByte( v ); | ||||
|                     count++; | ||||
|                 } | ||||
|                 for ( int i = count; i < linesize_mask; i++ ) { | ||||
|                     stream.WriteByte( 0x0 ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout( LayoutKind.Sequential, Pack = 1 )] | ||||
|     public struct IconFileHeader { | ||||
|         public ushort icoReserved; | ||||
|         public ushort icoResourceType; | ||||
|         public ushort icoResourceCount; | ||||
| 
 | ||||
|         public void Write( Stream stream ) { | ||||
|             byte[] buf; | ||||
|             buf = BitConverter.GetBytes( icoReserved ); | ||||
|             stream.Write( buf, 0, 2 ); | ||||
|             buf = BitConverter.GetBytes( icoResourceType ); | ||||
|             stream.Write( buf, 0, 2 ); | ||||
|             buf = BitConverter.GetBytes( icoResourceCount ); | ||||
|             stream.Write( buf, 0, 2 ); | ||||
|         } | ||||
| 
 | ||||
|         public static IconFileHeader Read( Stream fs ) { | ||||
|             IconFileHeader ifh = new IconFileHeader(); | ||||
|             byte[] buf = new byte[2]; | ||||
|             fs.Read( buf, 0, 2 ); | ||||
|             ifh.icoReserved = BitConverter.ToUInt16( buf, 0 ); | ||||
|             fs.Read( buf, 0, 2 ); | ||||
|             ifh.icoResourceType = BitConverter.ToUInt16( buf, 0 ); | ||||
|             fs.Read( buf, 0, 2 ); | ||||
|             ifh.icoResourceCount = BitConverter.ToUInt16( buf, 0 ); | ||||
|             return ifh; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     [StructLayout( LayoutKind.Sequential, Pack = 1 )] | ||||
|     public struct IconInfoHeader { | ||||
|         public byte Width; | ||||
|         public byte Height; | ||||
|         public byte ColorCount; | ||||
|         public byte Reserved1; | ||||
|         public ushort Reserved2; | ||||
|         public ushort Reserved3; | ||||
|         public uint icoDIBSize; | ||||
|         public uint icoDIBOffset; | ||||
| 
 | ||||
|         public override string ToString() { | ||||
|             return "{Width=" + Width + ", Height=" + Height + ", ColorCount=" + ColorCount + ", Reserved1=" + Reserved1 + ", Reserved2=" + Reserved2 + ", Reserved3=" + Reserved3 + ", icoDIBSize=" + icoDIBSize + ", icoDIBOffset=" + icoDIBOffset + "}"; | ||||
|         } | ||||
| 
 | ||||
|         public void Write( Stream stream ) { | ||||
|             byte[] buf; | ||||
|             stream.WriteByte( Width ); | ||||
|             stream.WriteByte( Height ); | ||||
|             stream.WriteByte( ColorCount ); | ||||
|             stream.WriteByte( Reserved1 ); | ||||
|             buf = BitConverter.GetBytes( Reserved2 ); | ||||
|             stream.Write( buf, 0, 2 ); | ||||
|             buf = BitConverter.GetBytes( Reserved3 ); | ||||
|             stream.Write( buf, 0, 2 ); | ||||
|             buf = BitConverter.GetBytes( icoDIBSize ); | ||||
|             stream.Write( buf, 0, 4 ); | ||||
|             buf = BitConverter.GetBytes( icoDIBOffset ); | ||||
|             stream.Write( buf, 0, 4 ); | ||||
|         } | ||||
| 
 | ||||
|         public static IconInfoHeader Read( Stream stream ) { | ||||
|             IconInfoHeader iih = new IconInfoHeader(); | ||||
|             iih.Width = (byte)stream.ReadByte(); | ||||
|             iih.Height = (byte)stream.ReadByte(); | ||||
|             iih.ColorCount = (byte)stream.ReadByte(); | ||||
|             iih.Reserved1 = (byte)stream.ReadByte(); | ||||
|             byte[] buf = new byte[4]; | ||||
|             stream.Read( buf, 0, 4 ); | ||||
|             iih.Reserved2 = BitConverter.ToUInt16( buf, 0 ); | ||||
|             iih.Reserved3 = BitConverter.ToUInt16( buf, 2 ); | ||||
|             stream.Read( buf, 0, 4 ); | ||||
|             iih.icoDIBSize = BitConverter.ToUInt32( buf, 0 ); | ||||
|             stream.Read( buf, 0, 4 ); | ||||
|             iih.icoDIBOffset = BitConverter.ToUInt32( buf, 0 ); | ||||
|             return iih; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										9
									
								
								trunk/Boare.Lib.AppUtil/DockPanelContainer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								trunk/Boare.Lib.AppUtil/DockPanelContainer.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| using System; | ||||
| using System.Windows.Forms; | ||||
| 
 | ||||
| namespace Boare.Lib.AppUtil { | ||||
| 
 | ||||
|     public class DockPanelContainer : Panel { | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										31
									
								
								trunk/Boare.Lib.AppUtil/MessageBodyEntry.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								trunk/Boare.Lib.AppUtil/MessageBodyEntry.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| /* | ||||
|  * MessageBody.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.AppUtil. | ||||
|  * | ||||
|  * Boare.Lib.AppUtil is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.AppUtil is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Boare.Lib.AppUtil { | ||||
| 
 | ||||
|     public class MessageBodyEntry { | ||||
|         public string Message; | ||||
|         public List<string> Location = new List<string>(); | ||||
| 
 | ||||
|         public MessageBodyEntry( string message, string[] location ) { | ||||
|             Message = message; | ||||
|             for ( int i = 0; i < location.Length; i++ ) { | ||||
|                 Location.Add( location[i] ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										84
									
								
								trunk/Boare.Lib.Media/MidiOutDevice.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								trunk/Boare.Lib.Media/MidiOutDevice.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| /* | ||||
|  * MidiOutDevice.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Media. | ||||
|  * | ||||
|  * Boare.Lib.Media is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Media is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Windows.Forms; | ||||
| 
 | ||||
| using bocoree; | ||||
| 
 | ||||
| namespace Boare.Lib.Media { | ||||
| 
 | ||||
|     public unsafe class MidiOutDevice { | ||||
|         private IntPtr m_handle; | ||||
|         private uint m_device_id; | ||||
| 
 | ||||
|         public MidiOutDevice( uint device_id ) { | ||||
|             m_device_id = device_id; | ||||
|             windows.midiOutOpen( ref m_handle, m_device_id, null, 0, windows.CALLBACK_NULL ); | ||||
|         } | ||||
| 
 | ||||
|         public void Close() { | ||||
|             if ( !m_handle.Equals( IntPtr.Zero ) ) { | ||||
|                 windows.midiOutClose( m_handle ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ProgramChange( byte channel, byte program ) { | ||||
|             SendShort( new byte[] { (byte)(0xc0 | (channel & 0x0f)) , program, 0x0 } ); | ||||
|         } | ||||
| 
 | ||||
|         public void Play( byte channel, byte note, byte velocity ) { | ||||
|             SendShort( new byte[] { (byte)(0x90 | (channel & 0x0f)), note, velocity } ); | ||||
|         } | ||||
| 
 | ||||
|         public void SendData( byte[] data ) { | ||||
|             if ( 0 < data.Length && data.Length <= 4 ) { | ||||
|                 SendShort( data ); | ||||
|             } else { | ||||
|                 SendLong( data ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void SendShort( byte[] data ) { | ||||
|             uint message = 0; | ||||
|             for ( int i = 0; i < data.Length; i++ ) { | ||||
|                 message |= ((uint)data[i]) << (i * 8); | ||||
|             } | ||||
|             windows.midiOutShortMsg( m_handle, message ); | ||||
|         } | ||||
| 
 | ||||
|         private void SendLong( byte[] data ) { | ||||
|             MIDIHDR hdr = new MIDIHDR(); | ||||
|             GCHandle dataHandle = GCHandle.Alloc( data, GCHandleType.Pinned ); | ||||
|             uint size = (uint)sizeof( MIDIHDR ); | ||||
|             try { | ||||
|                 hdr.lpData = (byte*)dataHandle.AddrOfPinnedObject().ToPointer(); | ||||
|                 hdr.dwBufferLength = (uint)data.Length; | ||||
|                 hdr.dwFlags = 0; | ||||
|                 windows.midiOutPrepareHeader( m_handle, ref hdr, size ); | ||||
|                 while ( (hdr.dwFlags & windows.WHDR_PREPARED) != windows.WHDR_PREPARED ) { | ||||
|                     Application.DoEvents(); | ||||
|                 } | ||||
|                 windows.midiOutLongMsg( m_handle, ref hdr, size ); | ||||
|                 while ( (hdr.dwFlags & windows.WHDR_DONE) != windows.WHDR_DONE ) { | ||||
|                     Application.DoEvents(); | ||||
|                 } | ||||
|                 windows.midiOutUnprepareHeader( m_handle, ref hdr, size ); | ||||
|             } finally { | ||||
|                 dataHandle.Free(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -165,7 +165,7 @@ namespace Boare.Lib.Media { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class RawAvi2Writer { | ||||
|     public class RawAvi2Writer : IAviWriter { | ||||
|         public MainAVIHeader m_main_header; | ||||
|         public AVIStreamHeader m_stream_header; | ||||
|         //long currentIndex; | ||||
| @ -187,6 +187,26 @@ namespace Boare.Lib.Media { | ||||
|         int m_junk_length; | ||||
|         uint m_scale; | ||||
|         uint m_rate; | ||||
|         private int m_width; | ||||
|         private int m_height; | ||||
| 
 | ||||
|         public Size Size { | ||||
|             get { | ||||
|                 return new Size( m_width, m_height ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public uint Scale { | ||||
|             get { | ||||
|                 return m_scale; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public uint Rate { | ||||
|             get { | ||||
|                 return m_rate; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         internal float frameRate { | ||||
|             get { | ||||
| @ -200,7 +220,10 @@ namespace Boare.Lib.Media { | ||||
|         /// </summary> | ||||
|         /// <param name="file">書き込み対象のファイル</param> | ||||
|         /// <param name="frameRate">AVIファイルのフレームレート</param> | ||||
|         public void Open( string file, uint scale, uint rate ) { | ||||
|         // string file, uint scale, uint rate, int width, int height, IntPtr hwnd | ||||
|         public bool Open( string file, uint scale, uint rate, int width, int height, IntPtr hwnd ) { | ||||
|             m_width = width; | ||||
|             m_height = height; | ||||
|             this.m_stream = new BinaryWriter( new FileStream( file, FileMode.Create, FileAccess.Write ) ); | ||||
|             float fps = (float)rate / (float)scale; | ||||
|             this.m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);//  ! 1秒は10^6μ秒 | ||||
| @ -226,6 +249,7 @@ namespace Boare.Lib.Media { | ||||
|             m_std_index = new AVISTDINDEX( 0L ); | ||||
|             m_super_index = new AVISUPERINDEX( 0 ); | ||||
|             m_riff_position = 0x4; | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| @ -361,6 +385,10 @@ namespace Boare.Lib.Media { | ||||
|         public void AddFrame( Bitmap bmp ) { | ||||
|             int i, width, height, lineSize; | ||||
| 
 | ||||
|             if ( bmp.Width != m_width || bmp.Height != m_height ) { | ||||
|                 throw new Exception( "bitmap size mismatch" ); | ||||
|             } | ||||
| 
 | ||||
|             // BitmapDataからビットマップデータと、BITMPAINFOHEADERを取り出す | ||||
|             BitmapData bmpDat = bmp.LockBits( | ||||
|                     new Rectangle( 0, 0, (int)bmp.Width, (int)bmp.Height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb ); | ||||
| @ -370,8 +398,8 @@ namespace Boare.Lib.Media { | ||||
| 
 | ||||
|             if ( m_is_first ) {//then | ||||
|                 m_is_first = false; | ||||
|                 this.m_main_header.dwWidth = (uint)bmpDat.Width;// bmp%infoHeader%Width | ||||
|                 this.m_main_header.dwHeight = (uint)bmpDat.Height;// bmp%infoHeader%Height | ||||
|                 this.m_main_header.dwWidth = (uint)m_width; | ||||
|                 this.m_main_header.dwHeight = (uint)m_height; | ||||
|                 this.m_main_header.dwMaxBytesPerSec = (uint)(bmpDat.Stride * bmpDat.Height * this.frameRate);// bmp%infoHeader%SizeImage * avi%frameRate | ||||
|                 this.m_main_header.dwStreams = 1; | ||||
|                 this.m_main_header.dwSuggestedBufferSize = (uint)(bmpDat.Stride * bmpDat.Height);// bmp.infoHeader%SizeImage | ||||
|  | ||||
							
								
								
									
										73
									
								
								trunk/Boare.Lib.Vsq/AttackConfig.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								trunk/Boare.Lib.Vsq/AttackConfig.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| /* | ||||
|  * AttackConfig.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public class AttackConfig { | ||||
|         public int number; | ||||
|         public String file; | ||||
|         public String author; | ||||
|         public String vendor; | ||||
|         public NoteHeadHandle contents; | ||||
| 
 | ||||
|         public AttackConfig() { | ||||
|             contents = new NoteHeadHandle(); | ||||
|         } | ||||
| 
 | ||||
|         public void parseAic( String aic_file ) { | ||||
|             using ( StreamReader sr = new StreamReader( aic_file ) ) { | ||||
|                 String line; | ||||
|                 String current_entry = ""; | ||||
|                 String articulation = ""; | ||||
|                 while ( (line = sr.ReadLine()) != null ) { | ||||
|                     if ( line.StartsWith( "[" ) ) { | ||||
|                         current_entry = line; | ||||
|                         continue; | ||||
|                     } else if ( line == "" || line.StartsWith( ";" ) ) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     String[] spl = line.Split( new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries ); | ||||
|                     if ( spl.Length < 2 ) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     spl[0] = spl[0].Trim(); | ||||
|                     spl[1] = spl[1].Trim(); | ||||
|                     if ( current_entry == "[Common]" ) { | ||||
|                         if ( spl[0] == "Articulation" ) { | ||||
|                             articulation = spl[1]; | ||||
|                         } | ||||
|                     } else if ( current_entry == "[Parameter]" ) { | ||||
|                         if ( spl[0] == "Length" ) { | ||||
|                             try { | ||||
|                                 this.contents.Length = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "Duration" ) { | ||||
|                             try { | ||||
|                                 this.contents.Duration = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "Depth" ) { | ||||
|                             try { | ||||
|                                 this.contents.Depth = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -2,7 +2,7 @@ | ||||
|   <PropertyGroup> | ||||
|     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||
|     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||
|     <ProductVersion>9.0.30729</ProductVersion> | ||||
|     <ProductVersion>9.0.21022</ProductVersion> | ||||
|     <SchemaVersion>2.0</SchemaVersion> | ||||
|     <ProjectGuid>{673347F3-6FC2-4F82-9273-BF158E0F8CB1}</ProjectGuid> | ||||
|     <OutputType>Library</OutputType> | ||||
| @ -59,6 +59,7 @@ | ||||
|     <Reference Include="System.Xml" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Compile Include="AttackConfig.cs" /> | ||||
|     <Compile Include="BPPair.cs" /> | ||||
|     <Compile Include="PortUtil.cs" /> | ||||
|     <Compile Include="NRPN.cs" /> | ||||
| @ -66,6 +67,7 @@ | ||||
|     <Compile Include="SingerConfigSys.cs" /> | ||||
|     <Compile Include="SMF\MidiFile.cs" /> | ||||
|     <Compile Include="SymbolTable.cs" /> | ||||
|     <Compile Include="TransCodeUtil.cs" /> | ||||
|     <Compile Include="UstEnvelope.cs" /> | ||||
|     <Compile Include="UstEvent.cs" /> | ||||
|     <Compile Include="UstFile.cs" /> | ||||
| @ -74,9 +76,11 @@ | ||||
|     <Compile Include="UstVibrato.cs" /> | ||||
|     <Compile Include="VibratoBPList.cs" /> | ||||
|     <Compile Include="VibratoBPPair.cs" /> | ||||
|     <Compile Include="ExpressionConfigSys.cs" /> | ||||
|     <Compile Include="VibratoConfig.cs" /> | ||||
|     <Compile Include="VibratoType.cs" /> | ||||
|     <Compile Include="VocaloSingerConfigSys.cs" /> | ||||
|     <Compile Include="VocaloSysUtil.cs" /> | ||||
|     <Compile Include="VsqBPPair.cs" /> | ||||
|     <Compile Include="VsqEventList.cs" /> | ||||
|     <Compile Include="VsqNrpn.cs" /> | ||||
|     <Compile Include="NrpnData.cs" /> | ||||
|  | ||||
							
								
								
									
										113
									
								
								trunk/Boare.Lib.Vsq/ExpressionConfigSys.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								trunk/Boare.Lib.Vsq/ExpressionConfigSys.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,113 @@ | ||||
| /* | ||||
|  * ExpressionConfigSys.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Text; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public class ExpressionConfigSys { | ||||
|         private const int MAX_VIBRATO = 0x400; | ||||
|         private List<VibratoConfig> m_vibrato_configs; | ||||
|         private List<AttackConfig> m_attack_configs; | ||||
| 
 | ||||
|         public ExpressionConfigSys( String path_expdb ) { | ||||
|             m_vibrato_configs = new List<VibratoConfig>(); | ||||
|             m_attack_configs = new List<AttackConfig>(); | ||||
|             String expression = Path.Combine( path_expdb, "expression.map" ); | ||||
|             if ( !File.Exists( expression ) ) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             using ( FileStream fs = new FileStream( expression, FileMode.Open, FileAccess.Read ) ) { | ||||
|                 byte[] dat = new byte[8]; | ||||
|                 fs.Seek( 0x20, SeekOrigin.Begin ); | ||||
|                 for ( int i = 0; i < MAX_VIBRATO; i++ ) { | ||||
|                     fs.Read( dat, 0, 8 ); | ||||
|                     ulong value = VocaloSysUtil.makelong_le( dat ); | ||||
| 
 | ||||
|                     if ( value <= 0 ) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     String ved = Path.Combine( path_expdb, "vexp" + value + ".ved" ); | ||||
|                     if ( !File.Exists( ved ) ) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     String vexp_dir = Path.Combine( path_expdb, "vexp" + value ); | ||||
|                     if ( !Directory.Exists( vexp_dir ) ) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     string NL = (char)0x0D + "" + (char)0x0A; | ||||
|                     using ( FileStream fs_ved = new FileStream( ved, FileMode.Open, FileAccess.Read ) ){ | ||||
|                         byte[] byte_ved = new byte[fs_ved.Length]; | ||||
|                         fs_ved.Read( byte_ved, 0, byte_ved.Length ); | ||||
|                         TransCodeUtil.decodeBytes( ref byte_ved ); | ||||
|                         String str = new String( Encoding.ASCII.GetChars( byte_ved ) ); | ||||
|                         String[] spl = str.Split( new String[]{ NL }, StringSplitOptions.RemoveEmptyEntries ); | ||||
|                         String current_entry = ""; | ||||
|                         for ( int j = 0; j < spl.Length; j++ ) { | ||||
|                             if ( spl[j].StartsWith( "[" ) ) { | ||||
|                                 current_entry = spl[j]; | ||||
|                                 continue; | ||||
|                             } else if ( spl[j] == "" ) { | ||||
|                                 continue; | ||||
|                             } | ||||
|                             if ( current_entry.Equals( "[VIBRATO]" ) ) { | ||||
|                                 String[] spl2 = spl[j].Split( ',' ); | ||||
|                                 if ( spl2.Length < 6 ) { | ||||
|                                     continue; | ||||
|                                 } | ||||
|                                 // ex: 1,1,"normal","normal2_type1.aic","[Normal]:Type:1","Standard","YAMAHA",0 | ||||
|                                 VibratoConfig item = new VibratoConfig(); | ||||
|                                 item.number = int.Parse( spl2[0] ); | ||||
|                                 item.contents.IDS = spl2[2].Replace( "\"", "" ); | ||||
|                                 item.file = spl2[3].Replace( "\"", "" ); | ||||
|                                 item.contents.Caption = spl2[4].Replace( ":", " " ).Replace( "\"", "" ); | ||||
|                                 item.author = spl2[5].Replace( "\"", "" ); | ||||
|                                 item.vendor = spl2[6].Replace( "\"", "" ); | ||||
|                                 String aic_file = Path.Combine( vexp_dir, item.file ); | ||||
|                                 if ( !File.Exists( aic_file ) ) { | ||||
|                                     continue; | ||||
|                                 } | ||||
|                                 item.parseAic( aic_file ); | ||||
|                             } if ( current_entry == "[NOTEATTACK]" ) { | ||||
|                                 String[] spl2 = spl[j].Split( ',' ); | ||||
|                                 if ( spl2.Length < 6 ) { | ||||
|                                     continue; | ||||
|                                 } | ||||
|                                 // ex: 1,1,"normal","normal2_type1.aic","[Normal]:Type:1","Standard","YAMAHA",0 | ||||
|                                 AttackConfig  item = new AttackConfig(); | ||||
|                                 item.number = int.Parse( spl2[0] ); | ||||
|                                 item.contents.IDS = spl2[2].Replace( "\"", "" ); | ||||
|                                 item.file = spl2[3].Replace( "\"", "" ); | ||||
|                                 item.contents.Caption = spl2[4].Replace( ":", " " ).Replace( "\"", "" ); | ||||
|                                 item.author = spl2[5].Replace( "\"", "" ); | ||||
|                                 item.vendor = spl2[6].Replace( "\"", "" ); | ||||
|                                 String aic_file = Path.Combine( vexp_dir, item.file ); | ||||
|                                 if ( !File.Exists( aic_file ) ) { | ||||
|                                     continue; | ||||
|                                 } | ||||
|                                 item.parseAic( aic_file ); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -16,6 +16,20 @@ using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public class Vector<T> : List<T> { | ||||
|         public int size() { | ||||
|             return base.Count; | ||||
|         } | ||||
| 
 | ||||
|         public T get( int index ) { | ||||
|             return base[index]; | ||||
|         } | ||||
| 
 | ||||
|         public void set( int index, T value ) { | ||||
|             base[index] = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public interface Iterator { | ||||
|         bool hasNext(); | ||||
|         object next(); | ||||
|  | ||||
| @ -21,9 +21,36 @@ namespace Boare.Lib.Vsq { | ||||
|     /// midiイベント。メタイベントは、メタイベントのデータ長をData[1]に格納せず、生のデータをDataに格納するので、注意が必要 | ||||
|     /// </summary> | ||||
|     public struct MidiEvent : IComparable<MidiEvent> { | ||||
|         public long Clock; | ||||
|         public byte FirstByte; | ||||
|         public byte[] Data; | ||||
|         public long clock; | ||||
|         public byte firstByte; | ||||
|         public byte[] data; | ||||
| 
 | ||||
|         public long Clock { | ||||
|             get { | ||||
|                 return clock; | ||||
|             } | ||||
|             set { | ||||
|                 clock = value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public byte FirstByte { | ||||
|             get { | ||||
|                 return firstByte; | ||||
|             } | ||||
|             set { | ||||
|                 firstByte = value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public byte[] Data { | ||||
|             get { | ||||
|                 return data; | ||||
|             } | ||||
|             set { | ||||
|                 data = value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static void writeDeltaClock( Stream stream, long number ) { | ||||
|             bool[] bits = new bool[64]; | ||||
| @ -96,10 +123,10 @@ namespace Boare.Lib.Vsq { | ||||
|                 // 3byte使用するシステムメッセージ | ||||
|                 //     0xF2: ソングポジション・ポインタ | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.Data = new byte[2]; | ||||
|                 stream.Read( me.Data, 0, 2 ); | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 me.data = new byte[2]; | ||||
|                 stream.Read( me.data, 0, 2 ); | ||||
|                 return me; | ||||
|             } else if ( ctrl == 0xC0 || ctrl == 0xD0 || first_byte == 0xF1 || first_byte == 0xF2 ) { | ||||
|                 // 2byte使用するチャンネルメッセージ | ||||
| @ -109,10 +136,10 @@ namespace Boare.Lib.Vsq { | ||||
|                 //     0xF1: クォータフレーム | ||||
|                 //     0xF3: ソングセレクト | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.Data = new byte[1]; | ||||
|                 stream.Read( me.Data, 0, 1 ); | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 me.data = new byte[1]; | ||||
|                 stream.Read( me.data, 0, 1 ); | ||||
|                 return me; | ||||
|             } else if ( first_byte == 0xF6 ) { | ||||
|                 // 1byte使用するシステムメッセージ | ||||
| @ -125,38 +152,38 @@ namespace Boare.Lib.Vsq { | ||||
|                 //     0xFE: アクティブセンシング | ||||
|                 //     0xFF: システムリセット | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.Data = new byte[0]; | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 me.data = new byte[0]; | ||||
|                 return me; | ||||
|             } else if ( first_byte == 0xff ) { | ||||
|                 // メタイベント | ||||
|                 byte meta_event_type = (byte)stream.ReadByte(); | ||||
|                 long meta_event_length = readDeltaClock( stream ); | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.Data = new byte[meta_event_length + 1]; | ||||
|                 me.Data[0] = meta_event_type; | ||||
|                 stream.Read( me.Data, 1, (int)meta_event_length ); | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 me.data = new byte[meta_event_length + 1]; | ||||
|                 me.data[0] = meta_event_type; | ||||
|                 stream.Read( me.data, 1, (int)meta_event_length ); | ||||
|                 return me; | ||||
|             } else if ( first_byte == 0xf0 ) { | ||||
|                 // f0ステータスのSysEx | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 long sysex_length = readDeltaClock( stream ); | ||||
|                 me.Data = new byte[sysex_length + 1]; | ||||
|                 stream.Read( me.Data, 0, (int)(sysex_length + 1) ); | ||||
|                 me.data = new byte[sysex_length + 1]; | ||||
|                 stream.Read( me.data, 0, (int)(sysex_length + 1) ); | ||||
|                 return me; | ||||
|             } else if ( first_byte == 0xf7 ) { | ||||
|                 // f7ステータスのSysEx | ||||
|                 MidiEvent me = new MidiEvent(); | ||||
|                 me.Clock = last_clock; | ||||
|                 me.FirstByte = first_byte; | ||||
|                 me.clock = last_clock; | ||||
|                 me.firstByte = first_byte; | ||||
|                 long sysex_length = readDeltaClock( stream ); | ||||
|                 me.Data = new byte[sysex_length]; | ||||
|                 stream.Read( me.Data, 0, (int)sysex_length ); | ||||
|                 me.data = new byte[sysex_length]; | ||||
|                 stream.Read( me.data, 0, (int)sysex_length ); | ||||
|                 return me; | ||||
|             } else { | ||||
|                 throw new ApplicationException( "don't know how to process first_byte: 0x" + Convert.ToString( first_byte, 16 ) ); | ||||
| @ -164,40 +191,43 @@ namespace Boare.Lib.Vsq { | ||||
|         } | ||||
| 
 | ||||
|         public void writeData( Stream stream ) { | ||||
|             stream.WriteByte( FirstByte ); | ||||
|             if ( FirstByte == 0xff ) { | ||||
|                 stream.WriteByte( Data[0] ); | ||||
|                 writeDeltaClock( stream, Data.Length - 1 ); | ||||
|             stream.WriteByte( firstByte ); | ||||
|             if ( firstByte == 0xff ) { | ||||
|                 stream.WriteByte( data[0] ); | ||||
|                 writeDeltaClock( stream, data.Length - 1 ); | ||||
|                 //stream.WriteByte( (byte)(Data.Length - 1) ); | ||||
|                 stream.Write( Data, 1, Data.Length - 1 ); | ||||
|                 stream.Write( data, 1, data.Length - 1 ); | ||||
|             } else { | ||||
|                 stream.Write( Data, 0, Data.Length ); | ||||
|                 stream.Write( data, 0, data.Length ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int CompareTo( MidiEvent item ) { | ||||
|             return (int)(Clock - item.Clock); | ||||
|             return (int)(clock - item.clock); | ||||
|         } | ||||
| 
 | ||||
|         public static MidiEvent generateTimeSigEvent( int clock, int numerator, int denominator ) { | ||||
|             MidiEvent ret = new MidiEvent(); | ||||
|             ret.Clock = clock; | ||||
|             ret.FirstByte = 0xff; | ||||
|             byte b_numer = (byte)(Math.Log( numerator, 2 ) + 0.1); | ||||
|             ret.Data = new byte[5] { 0x58, (byte)denominator, b_numer, 0x18, 0x08 }; | ||||
|             ret.clock = clock; | ||||
|             ret.firstByte = 0xff; | ||||
|             byte b_numer = (byte)(Math.Log( denominator, 2 ) + 0.1); | ||||
| #if DEBUG | ||||
|             Console.WriteLine( "VsqEvent.generateTimeSigEvent; b_number=" + b_numer + "; denominator=" + denominator ); | ||||
| #endif | ||||
|             ret.data = new byte[5] { 0x58, (byte)numerator, b_numer, 0x18, 0x08 }; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static MidiEvent generateTempoChangeEvent( int clock, int tempo ) { | ||||
|             MidiEvent ret = new MidiEvent(); | ||||
|             ret.Clock = clock; | ||||
|             ret.FirstByte = 0xff; | ||||
|             ret.clock = clock; | ||||
|             ret.firstByte = 0xff; | ||||
|             byte b1 = (byte)(tempo & 0xff); | ||||
|             tempo = tempo >> 8; | ||||
|             byte b2 = (byte)(tempo & 0xff); | ||||
|             tempo = tempo >> 8; | ||||
|             byte b3 = (byte)(tempo & 0xff); | ||||
|             ret.Data = new byte[4] { 0x51, b3, b2, b1 }; | ||||
|             ret.data = new byte[4] { 0x51, b3, b2, b1 }; | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
| @ -259,7 +289,7 @@ namespace Boare.Lib.Vsq { | ||||
|                     int count = m_events[track].Count; | ||||
|                     for ( int i = 0; i < count; i++ ) { | ||||
|                         MidiEvent mi = m_events[track][i]; | ||||
|                         mi.Clock = mi.Clock * 480 / m_time_format; | ||||
|                         mi.clock = mi.clock * 480 / m_time_format; | ||||
|                         m_events[track][i] = mi; | ||||
|                     } | ||||
|                 } | ||||
| @ -275,36 +305,36 @@ namespace Boare.Lib.Vsq { | ||||
|                     byte msb, lsb, data_msb, data_lsb; | ||||
|                     msb = lsb = data_msb = data_lsb = 0x0; | ||||
|                     for ( int i = 0; i < m_events[track].Count; i++ ) { | ||||
|                         if ( m_events[track][i].FirstByte == 0xb0 ) { | ||||
|                             switch ( m_events[track][i].Data[0] ) { | ||||
|                         if ( m_events[track][i].firstByte == 0xb0 ) { | ||||
|                             switch ( m_events[track][i].data[0] ) { | ||||
|                                 case 0x63: | ||||
|                                     msb = m_events[track][i].Data[1]; | ||||
|                                     msb = m_events[track][i].data[1]; | ||||
|                                     lsb = 0x0; | ||||
|                                     break; | ||||
|                                 case 0x62: | ||||
|                                     lsb = m_events[track][i].Data[1]; | ||||
|                                     lsb = m_events[track][i].data[1]; | ||||
|                                     break; | ||||
|                                 case 0x06: | ||||
|                                     data_msb = m_events[track][i].Data[1]; | ||||
|                                     data_msb = m_events[track][i].data[1]; | ||||
|                                     ushort nrpn = (ushort)(msb << 8 | lsb); | ||||
|                                     string name = NRPN.getName( nrpn ); | ||||
|                                     if ( name == "" ) { | ||||
|                                         name = "* * UNKNOWN * *"; | ||||
|                                         sw.WriteLine( string.Format( format0, m_events[track][i].Clock, nrpn, name, data_msb ) ); | ||||
|                                         sw.WriteLine( string.Format( format0, m_events[track][i].clock, nrpn, name, data_msb ) ); | ||||
|                                     } else { | ||||
|                                         //if ( !NRPN.is_require_data_lsb( nrpn ) ) { | ||||
|                                             sw.WriteLine( string.Format( format0, m_events[track][i].Clock, nrpn, name, data_msb ) ); | ||||
|                                             sw.WriteLine( string.Format( format0, m_events[track][i].clock, nrpn, name, data_msb ) ); | ||||
|                                         //} | ||||
|                                     } | ||||
|                                     break; | ||||
|                                 case 0x26: | ||||
|                                     data_lsb = m_events[track][i].Data[1]; | ||||
|                                     data_lsb = m_events[track][i].data[1]; | ||||
|                                     ushort nrpn2 = (ushort)(msb << 8 | lsb); | ||||
|                                     string name2 = NRPN.getName( nrpn2 ); | ||||
|                                     if ( name2 == "" ) { | ||||
|                                         name2 = "* * UNKNOWN * *"; | ||||
|                                     } | ||||
|                                     sw.WriteLine( string.Format( format, m_events[track][i].Clock, nrpn2, name2, data_msb, data_lsb ) ); | ||||
|                                     sw.WriteLine( string.Format( format, m_events[track][i].clock, nrpn2, name2, data_msb, data_lsb ) ); | ||||
|                                     break; | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
| @ -29,6 +29,19 @@ namespace Boare.Lib.Vsq { | ||||
|         public int GenderFactor; | ||||
|         public int Original; | ||||
|         public int Program; | ||||
|         public int Resonance1Amplitude; | ||||
|         public int Resonance1Frequency; | ||||
|         public int Resonance1BandWidth; | ||||
|         public int Resonance2Amplitude; | ||||
|         public int Resonance2Frequency; | ||||
|         public int Resonance2BandWidth; | ||||
|         public int Resonance3Amplitude; | ||||
|         public int Resonance3Frequency; | ||||
|         public int Resonance3BandWidth; | ||||
|         public int Resonance4Amplitude; | ||||
|         public int Resonance4Frequency; | ||||
|         public int Resonance4BandWidth; | ||||
|         public int Harmonics; | ||||
| 
 | ||||
|         public SingerConfig() { | ||||
|         } | ||||
| @ -46,96 +59,23 @@ namespace Boare.Lib.Vsq { | ||||
|             ret.GenderFactor = GenderFactor; | ||||
|             ret.Original = Original; | ||||
|             ret.Program = Program; | ||||
|             ret.Resonance1Amplitude = Resonance1Amplitude; | ||||
|             ret.Resonance1Frequency = Resonance1Frequency; | ||||
|             ret.Resonance1BandWidth = Resonance1BandWidth; | ||||
|             ret.Resonance2Amplitude = Resonance2Amplitude; | ||||
|             ret.Resonance2Frequency = Resonance2Frequency; | ||||
|             ret.Resonance2BandWidth = Resonance2BandWidth; | ||||
|             ret.Resonance3Amplitude = Resonance3Amplitude; | ||||
|             ret.Resonance3Frequency = Resonance3Frequency; | ||||
|             ret.Resonance3BandWidth = Resonance3BandWidth; | ||||
|             ret.Resonance4Amplitude = Resonance4Amplitude; | ||||
|             ret.Resonance4Frequency = Resonance4Frequency; | ||||
|             ret.Resonance4BandWidth = Resonance4BandWidth; | ||||
|             ret.Harmonics = Harmonics; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static void decode_vvd_bytes( ref byte[] dat ) { | ||||
|             for ( int i = 0; i < dat.Length; i++ ) { | ||||
|                 byte M = (byte)(dat[i] >> 4); | ||||
|                 byte L = (byte)(dat[i] - (M << 4)); | ||||
|                 byte newM = endecode_vvd_m( M ); | ||||
|                 byte newL = endecode_vvd_l( L ); | ||||
|                 dat[i] = (byte)((newM << 4) | newL); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         static byte endecode_vvd_l( byte value ) { | ||||
|             switch ( value ) { | ||||
|                 case 0x0: | ||||
|                     return 0xa; | ||||
|                 case 0x1: | ||||
|                     return 0xb; | ||||
|                 case 0x2: | ||||
|                     return 0x8; | ||||
|                 case 0x3: | ||||
|                     return 0x9; | ||||
|                 case 0x4: | ||||
|                     return 0xe; | ||||
|                 case 0x5: | ||||
|                     return 0xf; | ||||
|                 case 0x6: | ||||
|                     return 0xc; | ||||
|                 case 0x7: | ||||
|                     return 0xd; | ||||
|                 case 0x8: | ||||
|                     return 0x2; | ||||
|                 case 0x9: | ||||
|                     return 0x3; | ||||
|                 case 0xa: | ||||
|                     return 0x0; | ||||
|                 case 0xb: | ||||
|                     return 0x1; | ||||
|                 case 0xc: | ||||
|                     return 0x6; | ||||
|                 case 0xd: | ||||
|                     return 0x7; | ||||
|                 case 0xe: | ||||
|                     return 0x4; | ||||
|                 case 0xf: | ||||
|                     return 0x5; | ||||
|             } | ||||
|             return 0x0; | ||||
|         } | ||||
| 
 | ||||
|         static byte endecode_vvd_m( byte value ) { | ||||
|             switch ( value ) { | ||||
|                 case 0x0: | ||||
|                     return 0x1; | ||||
|                 case 0x1: | ||||
|                     return 0x0; | ||||
|                 case 0x2: | ||||
|                     return 0x3; | ||||
|                 case 0x3: | ||||
|                     return 0x2; | ||||
|                 case 0x4: | ||||
|                     return 0x5; | ||||
|                 case 0x5: | ||||
|                     return 0x4; | ||||
|                 case 0x6: | ||||
|                     return 0x7; | ||||
|                 case 0x7: | ||||
|                     return 0x6; | ||||
|                 case 0x8: | ||||
|                     return 0x9; | ||||
|                 case 0x9: | ||||
|                     return 0x8; | ||||
|                 case 0xa: | ||||
|                     return 0xb; | ||||
|                 case 0xb: | ||||
|                     return 0xa; | ||||
|                 case 0xc: | ||||
|                     return 0xd; | ||||
|                 case 0xd: | ||||
|                     return 0xc; | ||||
|                 case 0xe: | ||||
|                     return 0xf; | ||||
|                 case 0xf: | ||||
|                     return 0xe; | ||||
|             } | ||||
|             return 0x0; | ||||
|         } | ||||
| 
 | ||||
|         public static SingerConfig readSingerConfig( string file, int original ) { | ||||
|         public static SingerConfig fromVvd( string file, int original ) { | ||||
|             SingerConfig sc = new SingerConfig(); | ||||
|             //original = original; | ||||
|             sc.ID = "VOCALOID:VIRTUAL:VOICE"; | ||||
| @ -154,14 +94,11 @@ namespace Boare.Lib.Vsq { | ||||
|                 int length = (int)fs.Length; | ||||
|                 byte[] dat = new byte[length]; | ||||
|                 fs.Read( dat, 0, length ); | ||||
|                 decode_vvd_bytes( ref dat ); | ||||
|                 for ( int i = 0; i < dat.Length - 1; i++ ) { | ||||
|                     if ( dat[i] == 0x17 && dat[i + 1] == 0x10 ) { | ||||
|                         dat[i] = 0x0d; | ||||
|                         dat[i + 1] = 0x0a; | ||||
|                     } | ||||
|                 } | ||||
|                 TransCodeUtil.decodeBytes( ref dat ); | ||||
|                 string str = bocoree.cp932.convert( dat ); | ||||
| #if DEBUG | ||||
|                 Console.WriteLine( "SingerConfig.readSingerConfig; str=" + str ); | ||||
| #endif | ||||
|                 string crlf = ((char)0x0d).ToString() + ((char)0x0a).ToString(); | ||||
|                 string[] spl = str.Split( new string[] { crlf }, StringSplitOptions.RemoveEmptyEntries ); | ||||
| 
 | ||||
| @ -176,6 +113,8 @@ namespace Boare.Lib.Vsq { | ||||
|                     id = id.Substring( 1, id.Length - 2 ); | ||||
|                     value = value.Substring( 1, value.Length - 2 ); | ||||
|                     value = value.Replace( "\\\"", "\"" ); | ||||
|                     int parsed_int = 64; | ||||
|                     int.TryParse( value, out parsed_int ); | ||||
|                     if ( id == "ID" ) { | ||||
|                         sc.ID = value; | ||||
|                     } else if ( id == "FORMAT" ) { | ||||
| @ -184,31 +123,42 @@ namespace Boare.Lib.Vsq { | ||||
|                         sc.VOICEIDSTR = value; | ||||
|                     } else if ( id == "VOICENAME" ) { | ||||
|                         sc.VOICENAME = value; | ||||
|                     } else if ( id == "Breathiness" ) { | ||||
|                         try { | ||||
|                             sc.Breathiness = int.Parse( value ); | ||||
|                         } catch { | ||||
|                         } | ||||
|                     } else if ( id == "Breathiness" || id == "Noise" ) { | ||||
|                         sc.Breathiness = parsed_int; | ||||
|                     } else if ( id == "Brightness" ) { | ||||
|                         try { | ||||
|                             sc.Brightness = int.Parse( value ); | ||||
|                         } catch { | ||||
|                         } | ||||
|                         sc.Brightness = parsed_int; | ||||
|                     } else if ( id == "Clearness" ) { | ||||
|                         try { | ||||
|                             sc.Clearness = int.Parse( value ); | ||||
|                         } catch { | ||||
|                         } | ||||
|                         sc.Clearness = parsed_int; | ||||
|                     } else if ( id == "Opening" ) { | ||||
|                         try { | ||||
|                             sc.Opening = int.Parse( value ); | ||||
|                         } catch { | ||||
|                         } | ||||
|                         sc.Opening = parsed_int; | ||||
|                     } else if ( id == "Gender:Factor" ) { | ||||
|                         try { | ||||
|                             sc.GenderFactor = int.Parse( value ); | ||||
|                         } catch { | ||||
|                         } | ||||
|                         sc.GenderFactor = parsed_int; | ||||
|                     } else if ( id == "Resonance1:Frequency" ) { | ||||
|                         sc.Resonance1Frequency = parsed_int; | ||||
|                     } else if ( id == "Resonance1:Band:Width" ) { | ||||
|                         sc.Resonance1BandWidth = parsed_int; | ||||
|                     } else if ( id == "Resonance1:Amplitude" ) { | ||||
|                         sc.Resonance1Amplitude = parsed_int; | ||||
|                     } else if ( id == "Resonance2:Frequency" ) { | ||||
|                         sc.Resonance2Frequency = parsed_int; | ||||
|                     } else if ( id == "Resonance2:Band:Width" ) { | ||||
|                         sc.Resonance2BandWidth = parsed_int; | ||||
|                     } else if ( id == "Resonance2:Amplitude" ) { | ||||
|                         sc.Resonance2Amplitude = parsed_int; | ||||
|                     } else if ( id == "Resonance3:Frequency" ) { | ||||
|                         sc.Resonance3Frequency = parsed_int; | ||||
|                     } else if ( id == "Resonance3:Band:Width" ) { | ||||
|                         sc.Resonance3BandWidth = parsed_int; | ||||
|                     } else if ( id == "Resonance3:Amplitude" ) { | ||||
|                         sc.Resonance3Amplitude = parsed_int; | ||||
|                     } else if ( id == "Resonance4:Frequency" ) { | ||||
|                         sc.Resonance4Frequency = parsed_int; | ||||
|                     } else if ( id == "Resonance4:Band:Width" ) { | ||||
|                         sc.Resonance4BandWidth = parsed_int; | ||||
|                     } else if ( id == "Resonance4:Amplitude" ) { | ||||
|                         sc.Resonance4Amplitude = parsed_int; | ||||
|                     } else if ( id == "Harmonics" ) { | ||||
|                         sc.Harmonics = parsed_int; | ||||
|                     } | ||||
|                 } | ||||
|             } catch { | ||||
|  | ||||
							
								
								
									
										142
									
								
								trunk/Boare.Lib.Vsq/SingerConfigSys.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								trunk/Boare.Lib.Vsq/SingerConfigSys.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | ||||
| /* | ||||
|  * SingerConfigSys.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public class SingerConfigSys { | ||||
|         private const int MAX_SINGERS = 0x4000; | ||||
| 
 | ||||
|         private List<SingerConfig> m_installed_singers = new List<SingerConfig>(); | ||||
|         private List<SingerConfig> m_singer_configs = new List<SingerConfig>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         ///  | ||||
|         /// </summary> | ||||
|         /// <param name="path_voicedb">音源のデータディレクトリ(ex:"C:\Program Files\VOCALOID2\voicedbdir")</param> | ||||
|         /// <param name="path_installed_singers">音源のインストールディレクトリ(ex:new string[]{ "C:\Program Files\VOCALOID2\voicedbdir\BXXXXXXXXXXXXXXX", "D:\singers\BNXXXXXXXXXX" })</param> | ||||
|         public SingerConfigSys( string path_voicedb, string[] path_installed_singers ) { | ||||
|             m_installed_singers = new List<SingerConfig>(); | ||||
|             m_singer_configs = new List<SingerConfig>(); | ||||
|             String map = Path.Combine( path_voicedb, "voice.map" ); | ||||
|             if ( !File.Exists( map ) ) { | ||||
|                 return; | ||||
|             } | ||||
|             using ( FileStream fs = new FileStream( map, FileMode.Open, FileAccess.Read ) ) { | ||||
|                 byte[] dat = new byte[8]; | ||||
|                 fs.Seek( 0x20, SeekOrigin.Begin ); | ||||
|                 for ( int i = 0; i < MAX_SINGERS; i++ ) { | ||||
|                     fs.Read( dat, 0, 8 ); | ||||
|                     ulong value = VocaloSysUtil.makelong_le( dat ); | ||||
|                     if ( value >= 1 ) { | ||||
|                         String vvd = Path.Combine( path_voicedb, "vvoice" + value + ".vvd" ); | ||||
|                         SingerConfig item = SingerConfig.fromVvd( vvd, 0 ); | ||||
|                         item.Program = i; | ||||
| 
 | ||||
|                         int original = -1; | ||||
|                         foreach ( SingerConfig sc in m_installed_singers ) { | ||||
|                             if ( sc.VOICEIDSTR == item.VOICEIDSTR ) { | ||||
|                                 original = sc.Program; | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
|                         if ( original < 0 ) { | ||||
|                             foreach ( String ipath in path_installed_singers ) { | ||||
|                                 if ( ipath.EndsWith( item.VOICEIDSTR ) ) { | ||||
|                                     string[] vvds = Directory.GetFiles( ipath, "*.vvd" ); | ||||
|                                     if ( vvds.Length > 0 ) { | ||||
|                                         original = m_installed_singers.Count; | ||||
|                                         SingerConfig installed = SingerConfig.fromVvd( vvds[0], original ); | ||||
|                                         installed.Program = original; | ||||
|                                         m_installed_singers.Add( installed ); | ||||
|                                         break; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         item.Original = original; | ||||
|                         m_singer_configs.Add( item ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public SingerConfig[] getInstalledSingers() { | ||||
|             return m_installed_singers.ToArray(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the VsqID of program change. | ||||
|         /// </summary> | ||||
|         /// <param name="program_change"></param> | ||||
|         /// <returns></returns>         | ||||
|         public VsqID getSingerID( string singer ) { | ||||
|             VsqID ret = new VsqID( 0 ); | ||||
|             ret.type = VsqIDType.Singer; | ||||
|             SingerConfig sc = null; | ||||
|             for ( int i = 0; i < m_singer_configs.Count; i++ ) { | ||||
|                 if ( m_singer_configs[i].VOICENAME == singer ) { | ||||
|                     sc = m_singer_configs[i]; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if ( sc == null ) { | ||||
|                 sc = new SingerConfig(); | ||||
|             } | ||||
|             int lang = 0; | ||||
|             foreach ( SingerConfig sc2 in m_installed_singers ) { | ||||
|                 if ( sc.VOICEIDSTR == sc2.VOICEIDSTR ) { | ||||
|                     lang = (int)VocaloSysUtil.getLanguageFromName( sc.VOICENAME ); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             ret.IconHandle = new IconHandle(); | ||||
|             ret.IconHandle.IconID = "$0701" + sc.Program.ToString( "0000" ); | ||||
|             ret.IconHandle.IDS = sc.VOICENAME; | ||||
|             ret.IconHandle.Index = 0; | ||||
|             ret.IconHandle.Language = lang; | ||||
|             ret.IconHandle.Length = 1; | ||||
|             ret.IconHandle.Original = sc.Original; | ||||
|             ret.IconHandle.Program = sc.Program; | ||||
|             ret.IconHandle.Caption = ""; | ||||
|             return ret; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Gets the singer information of pecified program change. | ||||
|         /// </summary> | ||||
|         /// <param name="program_change"></param> | ||||
|         /// <returns></returns> | ||||
|         public SingerConfig getSingerInfo( string singer ) { | ||||
|             foreach ( SingerConfig item in m_singer_configs ) { | ||||
|                 if ( item.VOICENAME == singer ) { | ||||
|                     return item; | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the list of singer configs. | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         public SingerConfig[] getSingerConfigs() { | ||||
|             return m_singer_configs.ToArray(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -18,109 +18,86 @@ using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// メモリー上でテキストファイルを扱うためのクラス. | ||||
|     /// </summary> | ||||
|     public class TextMemoryStream : IDisposable { | ||||
|         FileAccess m_access; | ||||
|         MemoryStream m_ms = null; | ||||
|         Encoding m_enc; | ||||
|         byte[] NEW_LINE; | ||||
|         private static readonly string NL = (char)0x0d + "" + (char)0x0a; | ||||
| 
 | ||||
|         private List<string> m_lines; | ||||
|         private int m_index; | ||||
| 
 | ||||
|         public TextMemoryStream() { | ||||
|             m_lines = new List<string>(); | ||||
|             m_lines.Add( "" ); | ||||
|             m_index = 0; | ||||
|         } | ||||
| 
 | ||||
|         public TextMemoryStream( string path, Encoding encoding ) { | ||||
|             m_lines = new List<string>(); | ||||
|             m_index = 0; | ||||
|             if ( File.Exists( path ) ) { | ||||
|                 using ( StreamReader sr = new StreamReader( path, encoding ) ) { | ||||
|                     while ( sr.Peek() >= 0 ) { | ||||
|                         string line = sr.ReadLine(); | ||||
|                         m_lines.Add( line ); | ||||
|                         m_index++; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         ///  | ||||
|         /// </summary> | ||||
|         /// <param name="s"></param> | ||||
|         public void write( string value ) { | ||||
|             byte[] buff = m_enc.GetBytes( value ); | ||||
|             m_ms.Write( buff, 0, buff.Length ); | ||||
|             appendString( value ); | ||||
|         } | ||||
| 
 | ||||
|         public void writeLine( string value ) { | ||||
|             appendString( value + NL ); | ||||
|         } | ||||
| 
 | ||||
|         private void appendString( string value ) { | ||||
|             string[] lines = value.Split( new string[] { NL }, StringSplitOptions.None ); | ||||
|             List<string> lines2 = new List<string>(); | ||||
|             for ( int i = 0; i < lines.Length; i++ ) { | ||||
|                 string[] spl = lines[i].Split( (char)0x0d, (char)0x0a ); | ||||
|                 for ( int j = 0; j < spl.Length; j++ ) { | ||||
|                     lines2.Add( spl[j] ); | ||||
|                 } | ||||
|             } | ||||
|             int count = lines2.Count; | ||||
|             if ( count > 0 ) { | ||||
|                 m_lines[m_index] += lines2[0]; | ||||
|                 for ( int i = 1; i < count; i++ ) { | ||||
|                     m_lines.Add( lines2[i] ); | ||||
|                     m_index++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void rewind() { | ||||
|             m_ms.Seek( 0, SeekOrigin.Begin ); | ||||
|         } | ||||
| 
 | ||||
|         public void writeLine( string s ) { | ||||
|             byte[] buff = m_enc.GetBytes( s + Environment.NewLine ); | ||||
|             m_ms.Write( buff, 0, buff.Length ); | ||||
|         } | ||||
| 
 | ||||
|         public void close() { | ||||
|             if ( m_ms != null ) { | ||||
|                 m_ms.Close(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int peek() { | ||||
|             long current = m_ms.Position; | ||||
|             int ret = m_ms.ReadByte(); | ||||
|             m_ms.Seek( current, SeekOrigin.Begin ); | ||||
|             return ret; | ||||
|             m_index = 0; | ||||
|         } | ||||
| 
 | ||||
|         public string readLine() { | ||||
|             List<byte> buffer = new List<byte>(); | ||||
|             byte value; | ||||
|             int ret; | ||||
|             ret = m_ms.ReadByte(); | ||||
|             while ( ret >= 0 ) { | ||||
|                 value = (byte)ret; | ||||
|                 if ( value == NEW_LINE[0] ) { | ||||
|                     byte next; | ||||
|                     long current = m_ms.Position; //0x0Dを検出した直後のストリームの位置 | ||||
|                     for ( int i = 1; i < NEW_LINE.Length; i++ ) { | ||||
|                         ret = m_ms.ReadByte(); | ||||
|                         if ( ret >= 0 ) { | ||||
|                             next = (byte)ret; | ||||
|                             if ( next != NEW_LINE[i] ) { | ||||
|                                 m_ms.Seek( current, SeekOrigin.Begin ); | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|             m_index++; | ||||
|             return m_lines[m_index - 1]; | ||||
|         } | ||||
| 
 | ||||
|         public int peek() { | ||||
|             if ( m_index < m_lines.Count ) { | ||||
|                 if ( m_lines[m_index] == "" ) { | ||||
|                     return -1; | ||||
|                 } else { | ||||
|                     return (int)m_lines[m_index][0]; | ||||
|                 } | ||||
|                 buffer.Add( value ); | ||||
|                 ret = m_ms.ReadByte(); | ||||
|             } else { | ||||
|                 return -1; | ||||
|             } | ||||
|             return Encoding.Unicode.GetString( buffer.ToArray() ); | ||||
|         } | ||||
| 
 | ||||
|         public void close() { | ||||
|             m_lines.Clear(); | ||||
|         } | ||||
| 
 | ||||
|         public void Dispose() { | ||||
|             if ( m_ms != null ) { | ||||
|                 m_ms.Close(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public TextMemoryStream( string path, Encoding encode ) { | ||||
|             m_access = FileAccess.Read; | ||||
|             m_ms = new MemoryStream(); | ||||
|             m_enc = encode; | ||||
|             if ( File.Exists( path ) ) { | ||||
|                 using ( StreamReader sr = new StreamReader( path, encode ) ) { | ||||
|                     while ( sr.Peek() >= 0 ) { | ||||
|                         string line = sr.ReadLine(); | ||||
|                         byte[] buffer = m_enc.GetBytes( line + Environment.NewLine ); | ||||
|                         m_ms.Write( buffer, 0, buffer.Length ); | ||||
|                     } | ||||
|                 } | ||||
|                 m_ms.Seek( 0, SeekOrigin.Begin ); | ||||
|             } | ||||
|             NEW_LINE = m_enc.GetBytes( Environment.NewLine ); | ||||
|         } | ||||
| 
 | ||||
|         public TextMemoryStream( FileAccess access ) { | ||||
|             m_access = access; | ||||
|             m_ms = new MemoryStream(); | ||||
|             m_enc = Encoding.Unicode; | ||||
|             NEW_LINE = m_enc.GetBytes( Environment.NewLine ); | ||||
|         } | ||||
| 
 | ||||
|         public TextMemoryStream() { | ||||
|             m_access = FileAccess.Write; | ||||
|             m_ms = new MemoryStream(); | ||||
|             m_enc = Encoding.Unicode; | ||||
|             NEW_LINE = m_enc.GetBytes( Environment.NewLine ); | ||||
|             close(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										32
									
								
								trunk/Boare.Lib.Vsq/TransCodeUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								trunk/Boare.Lib.Vsq/TransCodeUtil.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public static class TransCodeUtil { | ||||
|         private static readonly byte[] MAP_L = new byte[] { 0xA, 0xB, 0x8, 0x9, 0xE, 0xF, 0xC, 0xD, 0x2, 0x3, 0x0, 0x1, 0x6, 0x7, 0x4, 0x5 }; | ||||
|         private static readonly byte[] MAP_R = new byte[] { 0x1, 0x0, 0x3, 0x2, 0x5, 0x4, 0x7, 0x6, 0x9, 0x8, 0xB, 0xA, 0xD, 0xC, 0xF, 0xE }; | ||||
|          | ||||
|         public static void decodeBytes( ref byte[] dat ) { | ||||
|             for ( int i = 0; i < dat.Length; i++ ) { | ||||
|                 byte M = (byte)(dat[i] >> 4); | ||||
|                 byte L = (byte)(dat[i] - (M << 4)); | ||||
|                 byte newM = endecode_vvd_m( M ); | ||||
|                 byte newL = endecode_vvd_l( L ); | ||||
|                 dat[i] = (byte)((newM << 4) | newL); | ||||
|             } | ||||
|             for ( int i = 0; i < dat.Length - 1; i++ ) { | ||||
|                 if ( dat[i] == 0x17 && dat[i + 1] == 0x10 ) { | ||||
|                     dat[i] = 0x0d; | ||||
|                     dat[i + 1] = 0x0a; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         static byte endecode_vvd_l( byte value ) { | ||||
|             return MAP_L[value]; | ||||
|         } | ||||
| 
 | ||||
|         static byte endecode_vvd_m( byte value ) { | ||||
|             return MAP_R[value]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										78
									
								
								trunk/Boare.Lib.Vsq/UstEnvelope.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								trunk/Boare.Lib.Vsq/UstEnvelope.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | ||||
| /* | ||||
|  * UstEnvelope.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     [Serializable] | ||||
|     public class UstEnvelope : ICloneable { | ||||
|         public int p1 = 0; | ||||
|         public int p2 = 5; | ||||
|         public int p3 = 35; | ||||
|         public int v1 = 0; | ||||
|         public int v2 = 100; | ||||
|         public int v3 = 100; | ||||
|         public int v4 = 0; | ||||
|         //public string Separator = ""; | ||||
|         public int p4 = 0; | ||||
|         public int p5 = 0; | ||||
|         public int v5 = 100; | ||||
| 
 | ||||
|         public UstEnvelope() { | ||||
|         } | ||||
| 
 | ||||
|         public UstEnvelope( string line ) { | ||||
|             if ( line.ToLower().StartsWith( "envelope=" ) ) { | ||||
|                 string[] spl = line.Split( '=' ); | ||||
|                 spl = spl[1].Split( ',' ); | ||||
|                 if ( spl.Length < 7 ) { | ||||
|                     return; | ||||
|                 } | ||||
|                 //Separator = ""; | ||||
|                 p1 = int.Parse( spl[0] ); | ||||
|                 p2 = int.Parse( spl[1] ); | ||||
|                 p3 = int.Parse( spl[2] ); | ||||
|                 v1 = int.Parse( spl[3] ); | ||||
|                 v2 = int.Parse( spl[4] ); | ||||
|                 v3 = int.Parse( spl[5] ); | ||||
|                 v4 = int.Parse( spl[6] ); | ||||
|                 if ( spl.Length == 11 ) { | ||||
|                     //Separator = "%"; | ||||
|                     p4 = int.Parse( spl[8] ); | ||||
|                     p5 = int.Parse( spl[9] ); | ||||
|                     v5 = int.Parse( spl[10] ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public object Clone() { | ||||
|             return new UstEnvelope( ToString() ); | ||||
|         } | ||||
| 
 | ||||
|         public override string ToString() { | ||||
|             string ret = "Envelope=" + p1 + "," + p2 + "," + p3 + "," + v1 + "," + v2 + "," + v3 + "," + v4; | ||||
|             ret += ",%," + p4 + "," + p5 + "," + v5; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public int getCount() { | ||||
|             //if ( Separator == "%" ) { | ||||
|                 return 5; | ||||
|             //} else { | ||||
|                 //return 4; | ||||
|             //} | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										151
									
								
								trunk/Boare.Lib.Vsq/UstPortamento.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								trunk/Boare.Lib.Vsq/UstPortamento.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | ||||
| /* | ||||
|  * UstPortamento.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     [Serializable] | ||||
|     public class UstPortamento : ICloneable { | ||||
|         public List<UstPortamentoPoint> Points = new List<UstPortamentoPoint>(); | ||||
|         public int Start; | ||||
| 
 | ||||
|         public void print( StreamWriter sw ) { | ||||
|             string pbw = ""; | ||||
|             string pby = ""; | ||||
|             string pbm = ""; | ||||
|             for ( int i = 0; i < Points.Count; i++ ) { | ||||
|                 string comma = (i == 0 ? "" : ","); | ||||
|                 pbw += comma + Points[i].Step; | ||||
|                 pby += comma + Points[i].Value; | ||||
|                 string type = ""; | ||||
|                 switch ( Points[i].Type ) { | ||||
|                     case UstPortamentoType.S: | ||||
|                         type = ""; | ||||
|                         break; | ||||
|                     case UstPortamentoType.Linear: | ||||
|                         type = "s"; | ||||
|                         break; | ||||
|                     case UstPortamentoType.R: | ||||
|                         type = "r"; | ||||
|                         break; | ||||
|                     case UstPortamentoType.J: | ||||
|                         type = "j"; | ||||
|                         break; | ||||
|                 } | ||||
|                 pbm += comma + type; | ||||
|             } | ||||
|             sw.WriteLine( "PBW=" + pbw ); | ||||
|             sw.WriteLine( "PBS=" + Start ); | ||||
|             sw.WriteLine( "PBY=" + pby ); | ||||
|             sw.WriteLine( "PBM=" + pbm ); | ||||
|         } | ||||
| 
 | ||||
|         public object Clone() { | ||||
|             UstPortamento ret = new UstPortamento(); | ||||
|             for ( int i = 0; i < Points.Count; i++ ) { | ||||
|                 ret.Points.Add( Points[i] ); | ||||
|             } | ||||
|             ret.Start = Start; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|         PBW=50,50,46,48,56,50,50,50,50 | ||||
|         PBS=-87 | ||||
|         PBY=-15.9,-20,-31.5,-26.6 | ||||
|         PBM=,s,r,j,s,s,s,s,s | ||||
|         */ | ||||
|         public void ParseLine( string line ) { | ||||
|             line = line.ToLower(); | ||||
|             string[] spl = line.Split( '=' ); | ||||
|             if ( spl.Length == 0 ) { | ||||
|                 return; | ||||
|             } | ||||
|             string[] values = spl[1].Split( ',' ); | ||||
|             if ( line.StartsWith( "pbs=" ) ) { | ||||
|                 Start = int.Parse( values[0] ); | ||||
|             } else if ( line.StartsWith( "pbw=" ) ) { | ||||
|                 for ( int i = 0; i < values.Length; i++ ) { | ||||
|                     if ( i >= Points.Count ) { | ||||
|                         Points.Add( new UstPortamentoPoint() ); | ||||
|                     } | ||||
|                     UstPortamentoPoint up = Points[i]; | ||||
|                     up.Step = int.Parse( values[i] ); | ||||
|                     Points[i] = up; | ||||
|                 } | ||||
|             } else if ( line.StartsWith( "pby=" ) ) { | ||||
|                 for ( int i = 0; i < values.Length; i++ ) { | ||||
|                     if ( i >= Points.Count ) { | ||||
|                         Points.Add( new UstPortamentoPoint() ); | ||||
|                     } | ||||
|                     UstPortamentoPoint up = Points[i]; | ||||
|                     up.Value = float.Parse( values[i] ); | ||||
|                     Points[i] = up; | ||||
|                 } | ||||
|             } else if ( line.StartsWith( "pbm=" ) ) { | ||||
|                 for ( int i = 0; i < values.Length; i++ ) { | ||||
|                     if ( i >= Points.Count ) { | ||||
|                         Points.Add( new UstPortamentoPoint() ); | ||||
|                     } | ||||
|                     UstPortamentoPoint up = Points[i]; | ||||
|                     switch ( values[i].ToLower() ) { | ||||
|                         case "s": | ||||
|                             up.Type = UstPortamentoType.Linear; | ||||
|                             break; | ||||
|                         case "r": | ||||
|                             up.Type = UstPortamentoType.R; | ||||
|                             break; | ||||
|                         case "j": | ||||
|                             up.Type = UstPortamentoType.J; | ||||
|                             break; | ||||
|                         default: | ||||
|                             up.Type = UstPortamentoType.S; | ||||
|                             break; | ||||
|                     } | ||||
|                     Points[i] = up; | ||||
|                 } | ||||
|             } else if ( line.StartsWith( "pbs=" ) ) { | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public struct UstPortamentoPoint { | ||||
|         public int Step; | ||||
|         public float Value; | ||||
|         public UstPortamentoType Type; | ||||
|     } | ||||
| 
 | ||||
|     public enum UstPortamentoType{ | ||||
|         /// <summary> | ||||
|         /// S型.表記は''(空文字) | ||||
|         /// </summary> | ||||
|         S, | ||||
|         /// <summary> | ||||
|         /// 直線型.表記は's' | ||||
|         /// </summary> | ||||
|         Linear, | ||||
|         /// <summary> | ||||
|         /// R型.表記は'r' | ||||
|         /// </summary> | ||||
|         R, | ||||
|         /// <summary> | ||||
|         /// J型.表記は'j' | ||||
|         /// </summary> | ||||
|         J, | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										89
									
								
								trunk/Boare.Lib.Vsq/UstVibrato.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								trunk/Boare.Lib.Vsq/UstVibrato.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| /* | ||||
|  * UstVibrato.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     [Serializable] | ||||
|     public class UstVibrato : ICloneable { | ||||
|         /// <summary> | ||||
|         /// 音符の長さに対する、パーセントで表したビブラートの長さ。 | ||||
|         /// </summary> | ||||
|         public float Length; | ||||
|         /// <summary> | ||||
|         /// ミリセカンドで表したビブラートによるピッチ振動の周期 | ||||
|         /// </summary> | ||||
|         public float Period; | ||||
|         /// <summary> | ||||
|         /// Centで表した、ビブラートによるピッチ振動の振幅。Peak to Peakは2*Depthとなる。 | ||||
|         /// </summary> | ||||
|         public float Depth; | ||||
|         /// <summary> | ||||
|         /// ビブラート長さに対する、パーセントで表したピッチ振動のフェードインの長さ。 | ||||
|         /// </summary> | ||||
|         public float In; | ||||
|         /// <summary> | ||||
|         /// ビブラートの長さに対するパーセントで表したピッチ振動のフェードアウトの長さ。 | ||||
|         /// </summary> | ||||
|         public float Out; | ||||
|         /// <summary> | ||||
|         /// ピッチ振動開始時の位相。2PIに対するパーセントで表す。 | ||||
|         /// </summary> | ||||
|         public float Phase; | ||||
|         /// <summary> | ||||
|         /// ピッチ振動の中心値と、音符の本来の音の高さからのずれ。Depthに対するパーセントで表す。 | ||||
|         /// </summary> | ||||
|         public float Shift; | ||||
|         public float Unknown = 100; | ||||
| 
 | ||||
|         public UstVibrato( string line ) { | ||||
|             if ( line.ToLower().StartsWith( "vbr=" ) ) { | ||||
|                 string[] spl = line.Split( '=' ); | ||||
|                 spl = spl[1].Split( ',' ); | ||||
|                 //VBR=65,180,70,20.0,17.6,82.8,49.8,100 | ||||
|                 if ( spl.Length >= 8 ) { | ||||
|                     Length = float.Parse( spl[0] ); | ||||
|                     Period = float.Parse( spl[1] ); | ||||
|                     Depth = float.Parse( spl[2] ); | ||||
|                     In = float.Parse( spl[3] ); | ||||
|                     Out = float.Parse( spl[4] ); | ||||
|                     Phase = float.Parse( spl[5] ); | ||||
|                     Shift = float.Parse( spl[6] ); | ||||
|                     Unknown = float.Parse( spl[7] ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public UstVibrato() { | ||||
|         } | ||||
| 
 | ||||
|         public override string ToString() { | ||||
|             return "VBR=" + Length + "," + Period + "," + Depth + "," + In + "," + Out + "," + Phase + "," + Shift + "," + Unknown; | ||||
|         } | ||||
| 
 | ||||
|         public object Clone() { | ||||
|             UstVibrato ret = new UstVibrato(); | ||||
|             ret.Length = Length; | ||||
|             ret.Period = Period; | ||||
|             ret.Depth = Depth; | ||||
|             ret.In = In; | ||||
|             ret.Out = Out; | ||||
|             ret.Phase = Phase; | ||||
|             ret.Shift = Shift; | ||||
|             ret.Unknown = Unknown; | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										132
									
								
								trunk/Boare.Lib.Vsq/VibratoConfig.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								trunk/Boare.Lib.Vsq/VibratoConfig.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | ||||
| /* | ||||
|  * VibratoConfig.cs | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public class VibratoConfig { | ||||
|         public int number; | ||||
|         public String file; | ||||
|         public String author; | ||||
|         public String vendor; | ||||
|         public VibratoHandle contents; | ||||
| 
 | ||||
|         public VibratoConfig() { | ||||
|             contents = new VibratoHandle(); | ||||
|         } | ||||
| 
 | ||||
|         public void parseAic( String aic_file ) { | ||||
|             using ( StreamReader sr = new StreamReader( aic_file ) ) { | ||||
|                 String line; | ||||
|                 String current_entry = ""; | ||||
|                 String articulation = ""; | ||||
|                 String depth_bpx = ""; | ||||
|                 String depth_bpy = ""; | ||||
|                 String rate_bpx = ""; | ||||
|                 String rate_bpy = ""; | ||||
|                 int depth_bpnum = 0; | ||||
|                 int rate_bpnum = 0; | ||||
|                 while ( (line = sr.ReadLine()) != null ) { | ||||
|                     if ( line.StartsWith( "[" ) ) { | ||||
|                         current_entry = line; | ||||
|                         continue; | ||||
|                     } else if ( line == "" || line.StartsWith( ";" ) ) { | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     String[] spl = line.Split( new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries ); | ||||
|                     if ( spl.Length < 2 ) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     spl[0] = spl[0].Trim(); | ||||
|                     spl[1] = spl[1].Trim(); | ||||
|                     if ( current_entry == "[Common]" ) { | ||||
|                         if ( spl[0] == "Articulation" ) { | ||||
|                             articulation = spl[1]; | ||||
|                         } | ||||
|                     } else if ( current_entry == "[Parameter]" ) { | ||||
|                         if ( spl[0] == "Length" ) { | ||||
|                             try { | ||||
|                                 this.contents.Length = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "StartDepth" ) { | ||||
|                             try { | ||||
|                                 this.contents.StartDepth = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "DepthBPNum" ) { | ||||
|                             try { | ||||
|                                 depth_bpnum = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "DepthBPX" ) { | ||||
|                             depth_bpx = spl[1]; | ||||
|                         } else if ( spl[0] == "DepthBPY" ) { | ||||
|                             depth_bpy = spl[1]; | ||||
|                         } else if ( spl[0] == "StartRate" ) { | ||||
|                             try { | ||||
|                                 this.contents.StartRate = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "RateBPNum" ) { | ||||
|                             try { | ||||
|                                 rate_bpnum = int.Parse( spl[1] ); | ||||
|                             } catch { } | ||||
|                         } else if ( spl[0] == "RateBPX" ) { | ||||
|                             rate_bpx = spl[1]; | ||||
|                         } else if ( spl[0] == "RateBPY" ) { | ||||
|                             rate_bpy = spl[1]; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if ( articulation != "Vibrato" ) { | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 // depth bp | ||||
|                 if ( depth_bpnum > 0 && depth_bpx != "" && depth_bpy != "" ) { | ||||
|                     String[] bpx = depth_bpx.Split( ',' ); | ||||
|                     String[] bpy = depth_bpy.Split( ',' ); | ||||
|                     if ( depth_bpnum == bpx.Length && depth_bpnum == bpy.Length ) { | ||||
|                         float[] x = new float[depth_bpnum]; | ||||
|                         int[] y = new int[depth_bpnum]; | ||||
|                         try { | ||||
|                             for ( int i = 0; i < depth_bpnum; i++ ) { | ||||
|                                 x[i] = float.Parse( bpx[i] ); | ||||
|                                 y[i] = int.Parse( bpy[i] ); | ||||
|                             } | ||||
|                             this.contents.DepthBP = new VibratoBPList( x, y ); | ||||
|                         } catch { } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // rate bp | ||||
|                 if ( rate_bpnum > 0 && rate_bpx != "" && rate_bpy != "" ) { | ||||
|                     String[] bpx = rate_bpx.Split( ',' ); | ||||
|                     String[] bpy = rate_bpy.Split( ',' ); | ||||
|                     if ( rate_bpnum == bpx.Length && rate_bpnum == bpy.Length ) { | ||||
|                         float[] x = new float[rate_bpnum]; | ||||
|                         int[] y = new int[rate_bpnum]; | ||||
|                         try { | ||||
|                             for ( int i = 0; i < rate_bpnum; i++ ) { | ||||
|                                 x[i] = float.Parse( bpx[i] ); | ||||
|                                 y[i] = int.Parse( bpy[i] ); | ||||
|                             } | ||||
|                             this.contents.RateBP = new VibratoBPList( x, y ); | ||||
|                         } catch { } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -100,9 +100,9 @@ namespace Boare.Lib.Vsq { | ||||
|                     return VibratoType.NormalType1; | ||||
|                 case "$04040002": | ||||
|                     return VibratoType.NormalType2; | ||||
|                 case  "$04040003": | ||||
|                 case "$04040003": | ||||
|                     return VibratoType.NormalType3; | ||||
|                 case "$0400004": | ||||
|                 case "$04040004": | ||||
|                     return VibratoType.NormalType4; | ||||
|                 case "$04040005": | ||||
|                     return VibratoType.ExtremeType1; | ||||
| @ -146,7 +146,7 @@ namespace Boare.Lib.Vsq { | ||||
|                 case VibratoType.NormalType3: | ||||
|                     return "$04040003"; | ||||
|                 case VibratoType.NormalType4: | ||||
|                     return "$0400004"; | ||||
|                     return "$04040004"; | ||||
|                 case VibratoType.ExtremeType1: | ||||
|                     return "$04040005"; | ||||
|                 case VibratoType.ExtremeType2: | ||||
|  | ||||
							
								
								
									
										791
									
								
								trunk/Boare.Lib.Vsq/VocaloSysUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										791
									
								
								trunk/Boare.Lib.Vsq/VocaloSysUtil.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,791 @@ | ||||
| /* | ||||
|  * VocaloSysUtil.s | ||||
|  * Copyright (c) 2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Collections.Generic; | ||||
| using Microsoft.Win32; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     using boolean = Boolean; | ||||
| 
 | ||||
|     public static class VocaloSysUtil{ | ||||
|         private static SingerConfigSys s_singer_config_sys1; | ||||
|         private static SingerConfigSys s_singer_config_sys2; | ||||
|         private static ExpressionConfigSys s_exp_config_sys1; | ||||
|         private static ExpressionConfigSys s_exp_config_sys2; | ||||
|         private static String s_path_vsti1; | ||||
|         private static String s_path_vsti2; | ||||
|         private static String s_path_editor1; | ||||
|         private static String s_path_editor2; | ||||
| 
 | ||||
|         static VocaloSysUtil() { | ||||
|             Vector<String> dir1 = new Vector<String>(); | ||||
|             RegistryKey key1 = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID", false ); | ||||
|             String header1 = "HKLM\\SOFTWARE\\VOCALOID"; | ||||
|             print( key1, header1, dir1 ); | ||||
|             key1.Close(); | ||||
|             String path_voicedb1; | ||||
|             String path_expdb1; | ||||
|             Vector<String> installed_singers1 = new Vector<String>(); | ||||
|             extract( dir1, | ||||
|                      header1,  | ||||
|                      out s_path_vsti1,  | ||||
|                      out path_voicedb1,  | ||||
|                      out path_expdb1,  | ||||
|                      out s_path_editor1, | ||||
|                      installed_singers1 ); | ||||
|             s_singer_config_sys1 = new SingerConfigSys( path_voicedb1, installed_singers1.ToArray() ); | ||||
|             s_exp_config_sys1 = new ExpressionConfigSys( path_expdb1 ); | ||||
| 
 | ||||
|             Vector<String> dir2 = new Vector<String>(); | ||||
|             RegistryKey key2 = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2", false ); | ||||
|             String header2 = "HKLM\\SOFTWARE\\VOCALOID2"; | ||||
|             print( key2, header2 , dir2 ); | ||||
|             key2.Close(); | ||||
|             String path_voicedb2; | ||||
|             String path_expdb2; | ||||
|             Vector<String> installed_singers2 = new Vector<String>(); | ||||
|             extract( dir2,  | ||||
|                      header2,  | ||||
|                      out s_path_vsti2,  | ||||
|                      out path_voicedb2,  | ||||
|                      out path_expdb2,  | ||||
|                      out s_path_editor2, | ||||
|                      installed_singers2 ); | ||||
|             s_singer_config_sys2 = new SingerConfigSys( path_voicedb2, installed_singers2.ToArray() ); | ||||
|             s_exp_config_sys2 = new ExpressionConfigSys( path_expdb2 ); | ||||
|         } | ||||
| 
 | ||||
|         private static void extract( Vector<String> dir, | ||||
|                                      String header, | ||||
|                                      out String path_vsti,  | ||||
|                                      out String path_voicedb,  | ||||
|                                      out String path_expdb,  | ||||
|                                      out String path_editor, | ||||
|                                      Vector<String> installed_singers ) { | ||||
|             Vector<String> application = new Vector<String>(); | ||||
|             Vector<String> expression = new Vector<String>(); | ||||
|             Vector<String> voice = new Vector<String>(); | ||||
|             path_vsti = ""; | ||||
|             path_expdb = ""; | ||||
|             path_voicedb = ""; | ||||
|             path_editor = ""; | ||||
|             foreach ( String s in dir ) { | ||||
|                 if ( s.StartsWith( header + "\\APPLICATION" ) ) { | ||||
|                     application.Add( s.Substring( (header + "\\APPLICATION").Length ) ); | ||||
|                 } else if ( s.StartsWith( header + "\\DATABASE\\EXPRESSION" ) ) { | ||||
|                     expression.Add( s.Substring( (header + "\\DATABASE\\EXPRESSION").Length ) ); | ||||
|                 } else if ( s.StartsWith( header + "\\DATABASE\\VOICE" ) ) { | ||||
|                     voice.Add( s.Substring( (header + "\\DATABASE\\VOICE\\").Length ) ); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // path_vstiを取得 | ||||
|             foreach ( String s in application ) { | ||||
|                 String[] spl = s.Split( '\t' ); | ||||
|                 if ( spl.Length >= 3 && spl[1].Equals( "PATH" ) ){ | ||||
|                     if ( spl[2].ToLower().EndsWith( ".dll" ) ) { | ||||
|                         path_vsti = spl[2]; | ||||
|                     } else if ( spl[2].ToLower().EndsWith( ".exe" ) ) { | ||||
|                         path_editor = spl[2]; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // path_vicedbを取得 | ||||
|             Vector<String> voice_ids = new Vector<String>(); | ||||
|             // 最初はpath_voicedbの取得と、id(BHXXXXXXXXXXXXXXXX)のようなシリアルを取得 | ||||
|             foreach ( String s in voice ) { | ||||
|                 String[] spl = s.Split( '\t' ); | ||||
|                 if ( spl.Length >= 2 ) { | ||||
|                     if ( spl[0].Equals( "VOICEDIR" ) ) { | ||||
|                         path_voicedb = spl[1]; | ||||
|                     } else if ( spl.Length >= 3 ) { | ||||
|                         String[] spl2 = spl[0].Split( '\\' ); | ||||
|                         if ( spl2.Length == 1 ) { | ||||
|                             if ( !voice_ids.Contains( spl2[0] ) ) { | ||||
|                                 voice_ids.Add( spl2[0] ); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // 取得したシリアルを元に、installed_singersを取得 | ||||
|             foreach ( String s in voice_ids ) { | ||||
|                 String install_dir = ""; | ||||
|                 foreach ( String s2 in voice ) { | ||||
|                     if ( s2.StartsWith( header + "\\" + s + "\t" ) ) { | ||||
|                         String[] spl = s2.Split( '\t' ); | ||||
|                         if ( spl.Length >= 3 && spl[1].Equals( "INSTALLDIR" ) ) { | ||||
|                             install_dir = Path.Combine( spl[2], s ); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if ( install_dir.Equals( "" ) ) { | ||||
|                     install_dir = Path.Combine( path_voicedb, s ); | ||||
|                 } | ||||
|                 installed_singers.Add( install_dir ); | ||||
|             } | ||||
| 
 | ||||
|             // path_expdbを取得 | ||||
|             Vector<String> exp_ids = new Vector<String>(); | ||||
|             // 最初はpath_expdbの取得と、id(BHXXXXXXXXXXXXXXXX)のようなシリアルを取得 | ||||
|             foreach ( String s in expression ) { | ||||
|                 String[] spl = s.Split( '\t' ); | ||||
|                 if ( spl.Length >= 2 ) { | ||||
|                     if ( spl[0].Equals( "EXPRESSIONDIR" ) ) { | ||||
|                         path_expdb = spl[1]; | ||||
|                     } else if ( spl.Length >= 3 ) { | ||||
|                         String[] spl2 = spl[0].Split( '\\' ); | ||||
|                         if ( spl2.Length == 1 ) { | ||||
|                             if ( !exp_ids.Contains( spl2[0] ) ) { | ||||
|                                 exp_ids.Add( spl2[0] ); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // 取得したシリアルを元に、installed_singersを取得 | ||||
|             /*foreach ( String s in exp_ids ) { | ||||
|                 String install_dir = ""; | ||||
|                 foreach ( String s2 in expression ) { | ||||
|                     if ( s2.StartsWith( header + "\\" + s + "\t" ) ) { | ||||
|                         String[] spl = s2.Split( '\t' ); | ||||
|                         if ( spl.Length >= 3 && spl[1].Equals( "INSTALLDIR" ) ) { | ||||
|                             install_dir = Path.Combine( spl[2], s ); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if ( install_dir.Equals( "" ) ) { | ||||
|                     install_dir = Path.Combine( path_expdb, s ); | ||||
|                 } | ||||
|                 installed_singers.Add( install_dir ); | ||||
|             }*/ | ||||
| 
 | ||||
| #if DEBUG | ||||
|             Console.WriteLine( "path_vsti=" + path_vsti ); | ||||
|             Console.WriteLine( "path_voicedb=" + path_voicedb ); | ||||
|             Console.WriteLine( "path_expdb=" + path_expdb ); | ||||
|             Console.WriteLine( "installed_singers=" ); | ||||
|             foreach ( String s in installed_singers ) { | ||||
|                 Console.WriteLine( "    " + s ); | ||||
|             } | ||||
| #endif | ||||
|         } | ||||
| 
 | ||||
|         // レジストリkey内の値を再帰的に検索し、ファイルfpに順次出力する | ||||
|         private static void print( RegistryKey key, String parent_name, Vector<String> list ){ | ||||
|             // 直下のキー内を再帰的にリストアップ | ||||
|             String[] subkeys = key.GetSubKeyNames(); | ||||
|             foreach( String s in subkeys ){ | ||||
|                 RegistryKey subkey = key.OpenSubKey( s, false ); | ||||
|                 print( subkey, parent_name + "\\" + s, list ); | ||||
|                 subkey.Close(); | ||||
|             } | ||||
| 
 | ||||
|             // 直下の値を出力 | ||||
|             String[] valuenames = key.GetValueNames(); | ||||
|             foreach( String s in valuenames ){ | ||||
|                 RegistryValueKind kind = key.GetValueKind( s ); | ||||
|                 if ( kind == RegistryValueKind.String ){ | ||||
|                     String str = parent_name + "\t" + s + "\t" + (String)key.GetValue( s ); | ||||
|                     list.Add( str ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the name of original singer of specified program change. | ||||
|         /// </summary> | ||||
|         /// <param name="singer"></param> | ||||
|         /// <returns></returns> | ||||
|         public static String getOriginalSinger1( String singer ) { | ||||
|             string voiceidstr = ""; | ||||
|             SingerConfig[] singer_configs = s_singer_config_sys1.getSingerConfigs(); | ||||
|             for ( int i = 0; i < singer_configs.Length; i++ ) { | ||||
|                 if ( singer.Equals( singer_configs[i].VOICENAME ) ) { | ||||
|                     voiceidstr = singer_configs[i].VOICEIDSTR; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if ( voiceidstr.Equals( "" ) ) { | ||||
|                 return ""; | ||||
|             } | ||||
|             SingerConfig[] installed_singers = s_singer_config_sys1.getInstalledSingers(); | ||||
|             for ( int i = 0; i < installed_singers.Length; i++ ) { | ||||
|                 if ( voiceidstr.Equals( installed_singers[i].VOICEIDSTR ) ) { | ||||
|                     return installed_singers[i].VOICENAME; | ||||
|                 } | ||||
|             } | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the name of original singer of specified program change. | ||||
|         /// </summary> | ||||
|         /// <param name="singer"></param> | ||||
|         /// <returns></returns> | ||||
|         public static String getOriginalSinger2( String singer ) { | ||||
|             string voiceidstr = ""; | ||||
|             SingerConfig[] singer_configs = s_singer_config_sys2.getSingerConfigs(); | ||||
|             for ( int i = 0; i < singer_configs.Length; i++ ) { | ||||
|                 if ( singer.Equals( singer_configs[i].VOICENAME ) ) { | ||||
|                     voiceidstr = singer_configs[i].VOICEIDSTR; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if ( voiceidstr.Equals( "" ) ) { | ||||
|                 return ""; | ||||
|             } | ||||
|             SingerConfig[] installed_singers = s_singer_config_sys2.getInstalledSingers(); | ||||
|             for ( int i = 0; i < installed_singers.Length; i++ ) { | ||||
|                 if ( voiceidstr.Equals( installed_singers[i].VOICEIDSTR ) ) { | ||||
|                     return installed_singers[i].VOICENAME; | ||||
|                 } | ||||
|             } | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         public static VsqID getSingerID1( String singer ) { | ||||
|             return s_singer_config_sys1.getSingerID( singer ); | ||||
|         } | ||||
| 
 | ||||
|         public static VsqID getSingerID2( String singer ) { | ||||
|             return s_singer_config_sys2.getSingerID( singer ); | ||||
|         } | ||||
| 
 | ||||
|         public static String getEditorPath1() { | ||||
|             return s_path_editor1; | ||||
|         } | ||||
| 
 | ||||
|         public static String getEditorPath2() { | ||||
|             return s_path_editor2; | ||||
|         } | ||||
| 
 | ||||
|         public static String getDllPathVsti1() { | ||||
|             return s_path_vsti1; | ||||
|         } | ||||
| 
 | ||||
|         public static String getDllPathVsti2() { | ||||
|             return s_path_vsti2; | ||||
|         } | ||||
| 
 | ||||
|         public static SingerConfig[] getSingerConfigs1() { | ||||
|             return s_singer_config_sys1.getSingerConfigs(); | ||||
|         } | ||||
| 
 | ||||
|         public static SingerConfig[] getSingerConfigs2() { | ||||
|             return s_singer_config_sys2.getSingerConfigs(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the voice language of specified program change | ||||
|         /// </summary> | ||||
|         /// <param name="name">name of singer</param> | ||||
|         /// <returns></returns> | ||||
|         public static VsqVoiceLanguage getLanguageFromName( string name ) { | ||||
|             switch ( name.ToLower() ) { | ||||
|                 case "meiko": | ||||
|                 case "kaito": | ||||
|                 case "miku": | ||||
|                 case "rin": | ||||
|                 case "len": | ||||
|                 case "rin_act2": | ||||
|                 case "len_act2": | ||||
|                 case "gackpoid": | ||||
|                 case "luka_jpn": | ||||
|                 case "megpoid": | ||||
|                     return VsqVoiceLanguage.Japanese; | ||||
|                 case "sweet_ann": | ||||
|                 case "prima": | ||||
|                 case "luka_eng": | ||||
|                 case "sonika": | ||||
|                     return VsqVoiceLanguage.English; | ||||
|             } | ||||
|             return VsqVoiceLanguage.Default; | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromPanLeft( int pan ) { | ||||
|             return pan / -64.0 + 1.0; | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromPanRight( int pan ) { | ||||
|             return pan / 64.0 + 1.0; | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromFeder( int feder ) { | ||||
|             return Math.Exp( -1.26697245e-02 + 1.18448420e-01 * feder / 10.0 ); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Transform the byte array(length=8) to unsigned long, assuming that the byte array is little endian. | ||||
|         /// </summary> | ||||
|         /// <param name="oct"></param> | ||||
|         /// <returns></returns> | ||||
|         public static ulong makelong_le( byte[] oct ) { | ||||
|             return (ulong)oct[7] << 56 | (ulong)oct[6] << 48 | (ulong)oct[5] << 40 | (ulong)oct[4] << 32 | (ulong)oct[3] << 24 | (ulong)oct[2] << 16 | (ulong)oct[1] << 8 | (ulong)oct[0]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static class VocaloSysUtil_ { | ||||
|         private static bool s_initialized = false; | ||||
| 
 | ||||
|         private static string s_dll_path2 = ""; | ||||
|         private static string s_editor_path2 = ""; | ||||
|         private static string s_voicedbdir2 = ""; | ||||
|         private static List<SingerConfig> s_installed_singers2 = new List<SingerConfig>(); | ||||
|         private static List<SingerConfig> s_singer_configs2 = new List<SingerConfig>(); | ||||
| 
 | ||||
|         private static string s_dll_path1 = ""; | ||||
|         private static string s_editor_path1 = ""; | ||||
|         private static string s_voicedbdir1 = ""; | ||||
|         private static List<SingerConfig> s_installed_singers1 = new List<SingerConfig>(); | ||||
|         private static List<SingerConfig> s_singer_configs1 = new List<SingerConfig>(); | ||||
| 
 | ||||
|         private const int MAX_SINGERS = 0x4000; | ||||
| 
 | ||||
|         static VocaloSysUtil_() { | ||||
|             init_vocalo2(); | ||||
|             init_vocalo1(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the name of original singer of specified program change. | ||||
|         /// </summary> | ||||
|         /// <param name="singer"></param> | ||||
|         /// <returns></returns> | ||||
|         public static string getOriginalSinger1( string singer ) { | ||||
|             string voiceidstr = ""; | ||||
|             for ( int i = 0; i < s_singer_configs1.Count; i++ ) { | ||||
|                 if ( singer == s_singer_configs1[i].VOICENAME ) { | ||||
|                     voiceidstr = s_singer_configs1[i].VOICEIDSTR; | ||||
|                 } | ||||
|             } | ||||
|             if ( voiceidstr == "" ) { | ||||
|                 return ""; | ||||
|             } | ||||
|             for ( int i = 0; i < s_installed_singers1.Count; i++ ) { | ||||
|                 if ( voiceidstr == s_installed_singers1[i].VOICEIDSTR ) { | ||||
|                     return s_installed_singers1[i].VOICENAME; | ||||
|                 } | ||||
|             } | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the name of original singer of specified program change. | ||||
|         /// </summary> | ||||
|         /// <param name="singer"></param> | ||||
|         /// <returns></returns> | ||||
|         public static string getOriginalSinger2( string singer ) { | ||||
|             string voiceidstr = ""; | ||||
|             for ( int i = 0; i < s_singer_configs2.Count; i++ ) { | ||||
|                 if ( singer == s_singer_configs2[i].VOICENAME ) { | ||||
|                     voiceidstr = s_singer_configs2[i].VOICEIDSTR; | ||||
|                 } | ||||
|             } | ||||
|             if ( voiceidstr == "" ) { | ||||
|                 return ""; | ||||
|             } | ||||
|             for ( int i = 0; i < s_installed_singers2.Count; i++ ) { | ||||
|                 if ( voiceidstr == s_installed_singers2[i].VOICEIDSTR ) { | ||||
|                     return s_installed_singers2[i].VOICENAME; | ||||
|                 } | ||||
|             } | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the voice language of specified program change | ||||
|         /// </summary> | ||||
|         /// <param name="name">name of singer</param> | ||||
|         /// <returns></returns> | ||||
|         public static VsqVoiceLanguage getLanguageFromName( string name ) { | ||||
|             switch ( name ) { | ||||
|                 case "MEIKO": | ||||
|                 case "KAITO": | ||||
|                 case "Miku": | ||||
|                 case "Rin": | ||||
|                 case "Len": | ||||
|                 case "Rin_ACT2": | ||||
|                 case "Len_ACT2": | ||||
|                 case "Gackpoid": | ||||
|                 case "Luka_JPN": | ||||
|                 case "Megpoid": | ||||
|                     return VsqVoiceLanguage.Japanese; | ||||
|                 case "Sweet_Ann": | ||||
|                 case "Prima": | ||||
|                 case "Luka_ENG": | ||||
|                     return VsqVoiceLanguage.English; | ||||
|             } | ||||
|             return VsqVoiceLanguage.Default; | ||||
|         } | ||||
| 
 | ||||
|         public static VsqID getSingerID1( string singer_name ) { | ||||
|             VsqID ret = new VsqID( 0 ); | ||||
|             ret.type = VsqIDType.Singer; | ||||
|             SingerConfig sc = null; | ||||
|             for ( int i = 0; i < s_singer_configs1.Count; i++ ) { | ||||
|                 if ( s_singer_configs1[i].VOICENAME == singer_name ) { | ||||
|                     sc = s_singer_configs1[i]; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if ( sc == null ) { | ||||
|                 sc = new SingerConfig(); | ||||
|             } | ||||
|             int lang = 0; | ||||
|             foreach ( SingerConfig sc2 in s_installed_singers1 ) { | ||||
|                 if ( sc.VOICEIDSTR == sc2.VOICEIDSTR ) { | ||||
|                     lang = (int)getLanguageFromName( sc.VOICENAME ); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             ret.IconHandle = new IconHandle(); | ||||
|             ret.IconHandle.IconID = "$0701" + sc.Program.ToString( "0000" ); | ||||
|             ret.IconHandle.IDS = sc.VOICENAME; | ||||
|             ret.IconHandle.Index = 0; | ||||
|             ret.IconHandle.Language = lang; | ||||
|             ret.IconHandle.Length = 1; | ||||
|             ret.IconHandle.Original = sc.Original; | ||||
|             ret.IconHandle.Program = sc.Program; | ||||
|             ret.IconHandle.Caption = ""; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static VsqID getSingerID2( string singer_name ) { | ||||
|             VsqID ret = new VsqID( 0 ); | ||||
|             ret.type = VsqIDType.Singer; | ||||
|             SingerConfig sc = null; | ||||
|             for ( int i = 0; i < s_singer_configs2.Count; i++ ) { | ||||
|                 if ( s_singer_configs2[i].VOICENAME == singer_name ) { | ||||
|                     sc = s_singer_configs2[i]; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if ( sc == null ) { | ||||
|                 sc = new SingerConfig(); | ||||
|             } | ||||
|             int lang = 0; | ||||
|             foreach ( SingerConfig sc2 in s_installed_singers2 ) { | ||||
|                 if ( sc.VOICEIDSTR == sc2.VOICEIDSTR ) { | ||||
|                     lang = (int)getLanguageFromName( sc.VOICENAME ); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             ret.IconHandle = new IconHandle(); | ||||
|             ret.IconHandle.IconID = "$0701" + sc.Program.ToString( "0000" ); | ||||
|             ret.IconHandle.IDS = sc.VOICENAME; | ||||
|             ret.IconHandle.Index = 0; | ||||
|             ret.IconHandle.Language = lang; | ||||
|             ret.IconHandle.Length = 1; | ||||
|             ret.IconHandle.Original = sc.Original; | ||||
|             ret.IconHandle.Program = sc.Program; | ||||
|             ret.IconHandle.Caption = ""; | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static SingerConfig[] getSingerConfigs1() { | ||||
|             return s_singer_configs1.ToArray(); | ||||
|         } | ||||
| 
 | ||||
|         public static SingerConfig[] getSingerConfigs2() { | ||||
|             return s_singer_configs2.ToArray(); | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromPanLeft( int pan ) { | ||||
|             return pan / -64.0 + 1.0; | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromPanRight( int pan ) { | ||||
|             return pan / 64.0 + 1.0; | ||||
|         } | ||||
| 
 | ||||
|         public static double getAmplifyCoeffFromFeder( int feder ) { | ||||
|             return Math.Exp( -1.26697245e-02 + 1.18448420e-01 * feder / 10.0 ); | ||||
|         } | ||||
| 
 | ||||
|         public static string getEditorPath2() { | ||||
|             return s_editor_path2; | ||||
|         } | ||||
| 
 | ||||
|         public static string getEditorPath1() { | ||||
|             return s_editor_path1; | ||||
|         } | ||||
| 
 | ||||
|         public static string getDllPathVsti2() { | ||||
|             return s_dll_path2; | ||||
|         } | ||||
| 
 | ||||
|         public static string getDllPathVsti1() { | ||||
|             return s_dll_path1; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// VOCALOID1システムのプロパティを取得 | ||||
|         /// </summary> | ||||
|         private static void init_vocalo1() { | ||||
|             // vocaloid1 dll path | ||||
|             RegistryKey v1application = null; | ||||
|             v1application = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID\\APPLICATION", false ); | ||||
|             if ( v1application != null ) { | ||||
|                 string[] keys = v1application.GetSubKeyNames(); | ||||
|                 for ( int i = 0; i < keys.Length; i++ ) { | ||||
|                     RegistryKey key = v1application.OpenSubKey( keys[i], false ); | ||||
|                     if ( key != null ) { | ||||
|                         string name = (string)key.GetValue( "PATH" ); | ||||
|                         if ( name.ToLower().EndsWith( "\\vocaloid.dll" ) ) { | ||||
|                             s_dll_path1 = name; | ||||
|                         } else if ( name.ToLower().EndsWith( "\\vocaloid.exe" ) ) { | ||||
|                             s_editor_path1 = name; | ||||
|                         } | ||||
|                         key.Close(); | ||||
|                     } | ||||
|                 } | ||||
|                 v1application.Close(); | ||||
|             } | ||||
| 
 | ||||
|             // voicedbdir for vocaloid1 | ||||
|             RegistryKey v1database = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID\\DATABASE\\VOICE", false ); | ||||
|             if ( v1database != null ) { | ||||
|                 s_voicedbdir1 = (string)v1database.GetValue( "VOICEDIR", "" ); | ||||
| #if DEBUG | ||||
|                 Console.WriteLine( "s_voicedbdir1=" + s_voicedbdir1 ); | ||||
| #endif | ||||
|                 // インストールされている歌手のVOICEIDSTRを列挙 | ||||
|                 string[] singer_voiceidstrs = v1database.GetSubKeyNames(); | ||||
|                 List<string> vvoice_keys = new List<string>(); | ||||
|                 List<SingerConfig> vvoice_values = new List<SingerConfig>(); | ||||
|                 foreach ( string voiceidstr in singer_voiceidstrs ) { | ||||
|                     RegistryKey singer = v1database.OpenSubKey( voiceidstr ); | ||||
|                     if ( singer == null ) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     RegistryKey vvoice = singer.OpenSubKey( "vvoice" ); | ||||
|                     if ( vvoice != null ) { | ||||
|                         string[] vvoices = vvoice.GetValueNames(); | ||||
| 
 | ||||
|                         // インストールされた歌手の.vvdを読みにいく | ||||
|                         // installdir以下の、拡張子.vvdのファイルを探す | ||||
|                         foreach ( string file in Directory.GetFiles( Path.Combine( s_voicedbdir1, voiceidstr ), "*.vvd" ) ) { | ||||
|                             SingerConfig config = SingerConfig.fromVvd( file, 0 ); //とりあえずプログラムチェンジは0 | ||||
|                             s_installed_singers1.Add( config ); | ||||
|                         } | ||||
| 
 | ||||
|                         // vvoice*.vvdを読みにいく。 | ||||
|                         foreach ( string s in vvoices ) { | ||||
| #if DEBUG | ||||
|                             Console.WriteLine( "s=" + s ); | ||||
| #endif | ||||
|                             string file = Path.Combine( s_voicedbdir1, s + ".vvd" ); | ||||
|                             if ( File.Exists( file ) ) { | ||||
|                                 SingerConfig config = SingerConfig.fromVvd( file, 0 ); | ||||
|                                 vvoice_keys.Add( s ); | ||||
|                                 vvoice_values.Add( config ); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     singer.Close(); | ||||
|                 } | ||||
| 
 | ||||
|                 // voice.mapを読み込んで、s_singer_configs1のプログラムチェンジを更新する | ||||
|                 string map = Path.Combine( s_voicedbdir1, "voice.map" ); | ||||
|                 if ( File.Exists( map ) ) { | ||||
|                     using ( FileStream fs = new FileStream( map, FileMode.Open, FileAccess.Read ) ) { | ||||
|                         byte[] dat = new byte[8]; | ||||
|                         fs.Seek( 0x20, SeekOrigin.Begin ); | ||||
|                         for ( int i = 0; i < MAX_SINGERS; i++ ) { | ||||
|                             fs.Read( dat, 0, 8 ); | ||||
|                             ulong value = makelong_le( dat ); | ||||
|                             if ( value >= 1 ) { | ||||
| #if DEBUG | ||||
|                                 Console.WriteLine( "value=" + value ); | ||||
| #endif | ||||
|                                 for ( int j = 0; j < vvoice_keys.Count; j++ ) { | ||||
|                                     if ( vvoice_keys[j] == "vvoice" + value ) { | ||||
|                                         vvoice_values[j].Program = i; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // s_installed_singers1のSingerConfigのProgramとOriginalを適当に頒番する | ||||
|                 for ( int i = 0; i < s_installed_singers1.Count; i++ ) { | ||||
|                     s_installed_singers1[i].Program = i; | ||||
|                     s_installed_singers1[i].Original = i; | ||||
|                 } | ||||
| 
 | ||||
|                 // s_singer_configs1を更新 | ||||
|                 for ( int i = 0; i < vvoice_values.Count; i++ ) { | ||||
|                     for ( int j = 0; j < s_installed_singers1.Count; j++ ) { | ||||
|                         if ( vvoice_values[i].VOICEIDSTR == s_installed_singers1[j].VOICEIDSTR ) { | ||||
|                             vvoice_values[i].Original = s_installed_singers1[j].Program; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     s_singer_configs1.Add( vvoice_values[i] ); | ||||
|                 } | ||||
|                 v1database.Close(); | ||||
|             } | ||||
| #if DEBUG | ||||
|             Console.WriteLine( "installed" ); | ||||
|             foreach ( SingerConfig sc in s_installed_singers1 ) { | ||||
|                 Console.WriteLine( "VOICENAME=" + sc.VOICENAME + "; VOICEIDSTR=" + sc.VOICEIDSTR + "; Program=" + sc.Program + "; Original=" + sc.Original ); | ||||
|             } | ||||
|             Console.WriteLine( "singer configs" ); | ||||
|             foreach ( SingerConfig sc in s_singer_configs1 ) { | ||||
|                 Console.WriteLine( "VOICENAME=" + sc.VOICENAME + "; VOICEIDSTR=" + sc.VOICEIDSTR + "; Program=" + sc.Program + "; Original=" + sc.Original ); | ||||
|             } | ||||
| #endif | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// VOCALOID2システムのプロパティを取得 | ||||
|         /// </summary> | ||||
|         private static void init_vocalo2() { | ||||
|             // 最初はvstiとeditorのパスを取得 | ||||
|             RegistryKey v2application = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2\\APPLICATION", false ); | ||||
|             if ( v2application == null ) { | ||||
|                 v2application = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2_DEMO\\APPLICATION", false ); | ||||
|             } | ||||
|             if ( v2application != null ) { | ||||
|                 string[] keys = v2application.GetSubKeyNames(); | ||||
|                 for ( int i = 0; i < keys.Length; i++ ) { | ||||
|                     RegistryKey key = v2application.OpenSubKey( keys[i], false ); | ||||
|                     if ( key != null ) { | ||||
|                         string name = (string)key.GetValue( "PATH" ); | ||||
|                         if ( name.ToLower().EndsWith( "\\vocaloid2.dll" ) ) { | ||||
|                             s_dll_path2 = name; | ||||
|                         } else if ( name.ToLower().EndsWith( "\\vocaloid2_demo.dll" ) ) { | ||||
|                             s_dll_path2 = name; | ||||
|                         } else if ( name.ToLower().EndsWith( "\\vocaloid2.exe" ) ) { | ||||
|                             s_editor_path2 = name; | ||||
|                         } | ||||
|                         key.Close(); | ||||
|                     } | ||||
|                 } | ||||
|                 v2application.Close(); | ||||
|             } | ||||
| 
 | ||||
|             // 歌声データベースを取得 | ||||
|             RegistryKey v2database = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2\\DATABASE\\VOICE", false ); | ||||
|             if ( v2database != null ) { | ||||
|                 // データベース(というよりもvoice.map)が保存されているパスを取得 | ||||
|                 s_voicedbdir2 = (string)v2database.GetValue( "VOICEDIR", "" ); | ||||
|                 // インストールされている歌手のVOICEIDSTRを列挙 | ||||
|                 string[] singer_voiceidstrs = v2database.GetSubKeyNames(); | ||||
|                 List<string> vvoice_keys = new List<string>(); | ||||
|                 List<SingerConfig> vvoice_values = new List<SingerConfig>(); | ||||
|                 foreach ( string voiceidstr in singer_voiceidstrs ) { | ||||
|                     RegistryKey singer = v2database.OpenSubKey( voiceidstr ); | ||||
|                     if ( singer == null ) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     string installdir = (string)singer.GetValue( "INSTALLDIR", "" ); | ||||
| #if DEBUG | ||||
|                     Console.WriteLine( "installdir=" + installdir ); | ||||
| #endif | ||||
|                     RegistryKey vvoice = singer.OpenSubKey( "vvoice" ); | ||||
|                     if ( vvoice != null ) { | ||||
|                         string[] vvoices = vvoice.GetValueNames(); | ||||
| 
 | ||||
|                         // インストールされた歌手の.vvdを読みにいく | ||||
|                         // installdir以下の、拡張子.vvdのファイルを探す | ||||
|                         foreach ( string file in Directory.GetFiles( Path.Combine( installdir, voiceidstr ), "*.vvd" ) ) { | ||||
|                             SingerConfig config = SingerConfig.fromVvd( file, 0 ); //とりあえずプログラムチェンジは0 | ||||
|                             s_installed_singers2.Add( config ); | ||||
|                         } | ||||
| 
 | ||||
|                         // vvoice*.vvdを読みにいく。場所は、installdirではなく、s_voicedbdir2 | ||||
|                         foreach ( string s in vvoices ) { | ||||
|                             string file = Path.Combine( s_voicedbdir2, s + ".vvd" ); | ||||
|                             if ( File.Exists( file ) ) { | ||||
|                                 SingerConfig config = SingerConfig.fromVvd( file, 0 ); | ||||
|                                 vvoice_keys.Add( s ); | ||||
|                                 vvoice_values.Add( config ); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     singer.Close(); | ||||
|                 } | ||||
| 
 | ||||
|                 // voice.mapを読み込んで、s_singer_configs2のプログラムチェンジを更新する | ||||
|                 string map = Path.Combine( s_voicedbdir2, "voice.map" ); | ||||
|                 if ( File.Exists( map ) ) { | ||||
|                     using ( FileStream fs = new FileStream( map, FileMode.Open, FileAccess.Read ) ) { | ||||
|                         byte[] dat = new byte[8]; | ||||
|                         fs.Seek( 0x20, SeekOrigin.Begin ); | ||||
|                         for ( int i = 0; i < MAX_SINGERS; i++ ) { | ||||
|                             fs.Read( dat, 0, 8 ); | ||||
|                             ulong value = makelong_le( dat ); | ||||
|                             if ( value >= 1 ) { | ||||
| #if DEBUG | ||||
|                                 Console.WriteLine( "value=" + value ); | ||||
| #endif | ||||
|                                 for ( int j = 0; j < vvoice_keys.Count; j++ ) { | ||||
|                                     if ( vvoice_keys[j] == "vvoice" + value ) { | ||||
|                                         vvoice_values[j].Program = i; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // s_installed_singers2のSingerConfigのProgramとOriginalを適当に頒番する | ||||
|                 for ( int i = 0; i < s_installed_singers2.Count; i++ ) { | ||||
|                     s_installed_singers2[i].Program = i; | ||||
|                     s_installed_singers2[i].Original = i; | ||||
|                 } | ||||
| 
 | ||||
|                 // s_singer_configs2を更新 | ||||
|                 for ( int i = 0; i < vvoice_values.Count; i++ ) { | ||||
|                     for ( int j = 0; j < s_installed_singers2.Count; j++ ) { | ||||
|                         if ( vvoice_values[i].VOICEIDSTR == s_installed_singers2[j].VOICEIDSTR ) { | ||||
|                             vvoice_values[i].Original = s_installed_singers2[j].Program; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     s_singer_configs2.Add( vvoice_values[i] ); | ||||
|                 } | ||||
|                 v2database.Close(); | ||||
|             } | ||||
| #if DEBUG | ||||
|             Console.WriteLine( "installed" ); | ||||
|             foreach ( SingerConfig sc in s_installed_singers2 ) { | ||||
|                 Console.WriteLine( "VOICENAME=" + sc.VOICENAME + "; VOICEIDSTR=" + sc.VOICEIDSTR + "; Program=" + sc.Program + "; Original=" + sc.Original ); | ||||
|             } | ||||
|             Console.WriteLine( "singer configs" ); | ||||
|             foreach ( SingerConfig sc in s_singer_configs2 ) { | ||||
|                 Console.WriteLine( "VOICENAME=" + sc.VOICENAME + "; VOICEIDSTR=" + sc.VOICEIDSTR + "; Program=" + sc.Program + "; Original=" + sc.Original ); | ||||
|             } | ||||
| #endif | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Transform the byte array(length=8) to unsigned long, assuming that the byte array is little endian. | ||||
|         /// </summary> | ||||
|         /// <param name="oct"></param> | ||||
|         /// <returns></returns> | ||||
|         public static ulong makelong_le( byte[] oct ) { | ||||
|             return (ulong)oct[7] << 56 | (ulong)oct[6] << 48 | (ulong)oct[5] << 40 | (ulong)oct[4] << 32 | (ulong)oct[3] << 24 | (ulong)oct[2] << 16 | (ulong)oct[1] << 8 | (ulong)oct[0]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -23,16 +23,20 @@ namespace Boare.Lib.Vsq { | ||||
|     /// </summary> | ||||
|     [Serializable] | ||||
|     public class VsqBPList : ICloneable { | ||||
|         private SortedList<int, int> m_list = new SortedList<int, int>(); | ||||
|         private SortedList<int, VsqBPPair> m_list = new SortedList<int, VsqBPPair>(); | ||||
|         public int Default = 0; | ||||
|         public int Maximum = 127; | ||||
|         public int Minimum = 0; | ||||
|         /// <summary> | ||||
|         /// このリストに設定されたidの最大値.次にデータ点が追加されたときは,個の値+1がidとして利用される.削除された場合でも減らない | ||||
|         /// </summary> | ||||
|         private int m_max_id = 0; | ||||
| 
 | ||||
|         private class KeyClockIterator : Iterator { | ||||
|             private SortedList<int, int> m_list; | ||||
|             private SortedList<int, VsqBPPair> m_list; | ||||
|             private int m_pos; | ||||
| 
 | ||||
|             public KeyClockIterator( SortedList<int, int> list ) { | ||||
|             public KeyClockIterator( SortedList<int, VsqBPPair> list ) { | ||||
|                 m_list = list; | ||||
|                 m_pos = -1; | ||||
|             } | ||||
| @ -71,12 +75,13 @@ namespace Boare.Lib.Vsq { | ||||
|                 int count = -1; | ||||
|                 foreach ( int key in m_list.Keys ) { | ||||
|                     count++; | ||||
|                     ret += (count == 0 ? "" : "," ) + key + "=" + m_list[key]; | ||||
|                     ret += (count == 0 ? "" : "," ) + key + "=" + m_list[key].value; | ||||
|                 } | ||||
|                 return ret; | ||||
|             } | ||||
|             set { | ||||
|                 m_list.Clear(); | ||||
|                 m_max_id = 0; | ||||
|                 string[] spl = value.Split( ',' ); | ||||
|                 for ( int i = 0; i < spl.Length; i++ ) { | ||||
|                     string[] spl2 = spl[i].Split( '=' ); | ||||
| @ -84,7 +89,8 @@ namespace Boare.Lib.Vsq { | ||||
|                         continue; | ||||
|                     } | ||||
|                     try { | ||||
|                         m_list.Add( int.Parse( spl2[0] ), int.Parse( spl2[1] ) ); | ||||
|                         m_list.Add( int.Parse( spl2[0] ), new VsqBPPair( int.Parse( spl2[1] ), m_max_id + 1 ) ); | ||||
|                         m_max_id++; | ||||
|                     } catch ( Exception ex ) { | ||||
| #if DEBUG | ||||
|                         Console.WriteLine( "    ex=" + ex ); | ||||
| @ -115,6 +121,7 @@ namespace Boare.Lib.Vsq { | ||||
|             Default = default_value; | ||||
|             Maximum = maximum; | ||||
|             Minimum = minimum; | ||||
|             m_max_id = 0; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @ -169,21 +176,47 @@ namespace Boare.Lib.Vsq { | ||||
|         public void add( int clock, int value ) { | ||||
|             lock ( m_list ) { | ||||
|                 if ( m_list.ContainsKey( clock ) ) { | ||||
|                     m_list[clock] = value; | ||||
|                     VsqBPPair v = m_list[clock]; | ||||
|                     v.value = value; | ||||
|                     m_list[clock] = v; | ||||
|                 } else { | ||||
|                     m_list.Add( clock, value ); | ||||
|                     VsqBPPair v = new VsqBPPair( value, m_max_id + 1 ); | ||||
|                     m_max_id++; | ||||
|                     m_list.Add( clock, v ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int getElement( int index ) { | ||||
|             return m_list[m_list.Keys[index]]; | ||||
|             return m_list[m_list.Keys[index]].value; | ||||
|         } | ||||
| 
 | ||||
|         public int getKeyClock( int index ) { | ||||
|             return m_list.Keys[index]; | ||||
|         } | ||||
| 
 | ||||
|         public int findValueFromID( int id ) { | ||||
|             int c = m_list.Keys.Count; | ||||
|             foreach ( int key in m_list.Keys ) { | ||||
|                 if ( m_list[key].id == id ) { | ||||
|                     return m_list[key].value; | ||||
|                 } | ||||
|             } | ||||
|             return Default; | ||||
|         } | ||||
| 
 | ||||
|         public void setValueForID( int id, int value ) { | ||||
|             int c = m_list.Keys.Count; | ||||
|             foreach ( int key in m_list.Keys ) { | ||||
|                 if ( m_list[key].id == id ) { | ||||
|                     VsqBPPair v = m_list[key]; | ||||
|                     v.value = value; | ||||
|                     m_list[key] = v; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int getValue( int clock, ref int index ) { | ||||
|             if ( m_list.Count == 0 ) { | ||||
|                 return Default; | ||||
| @ -196,7 +229,7 @@ namespace Boare.Lib.Vsq { | ||||
|                     if ( clock < keyclock ) { | ||||
|                         if ( i > 0 ) { | ||||
|                             index = i; | ||||
|                             return m_list[m_list.Keys[i - 1]]; | ||||
|                             return m_list[m_list.Keys[i - 1]].value; | ||||
|                         } else { | ||||
|                             index = i; | ||||
|                             return Default; | ||||
| @ -204,7 +237,7 @@ namespace Boare.Lib.Vsq { | ||||
|                     } | ||||
|                 } | ||||
|                 index = m_list.Keys.Count - 1; | ||||
|                 return m_list[m_list.Keys[m_list.Keys.Count - 1]]; | ||||
|                 return m_list[m_list.Keys[m_list.Keys.Count - 1]].value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -216,38 +249,13 @@ namespace Boare.Lib.Vsq { | ||||
|                     int keyclock = m_list.Keys[i]; | ||||
|                     if ( clock < keyclock ) { | ||||
|                         if ( i > 0 ) { | ||||
|                             return m_list[m_list.Keys[i - 1]]; | ||||
|                             return m_list[m_list.Keys[i - 1]].value; | ||||
|                         } else { | ||||
|                             return Default; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return m_list[m_list.Keys[m_list.Keys.Count - 1]]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int OLD_getElement( int clock ) { | ||||
|             if ( m_list.Count == 0 ) { | ||||
|                 return Default; | ||||
|             } else { | ||||
|                 if ( m_list.ContainsKey( clock ) ) { | ||||
|                     return m_list[clock]; | ||||
|                 } else { | ||||
|                     int index = 0; | ||||
|                     int prev = 0; | ||||
|                     foreach ( int key in m_list.Keys ) { | ||||
|                         if ( clock < key ) { | ||||
|                             index = prev; | ||||
|                             break; | ||||
|                         } | ||||
|                         prev = key; | ||||
|                     } | ||||
|                     if ( m_list.ContainsKey( index ) ) { | ||||
|                         return m_list[index]; | ||||
|                     } else { | ||||
|                         return Default; | ||||
|                     } | ||||
|                 } | ||||
|                 return m_list[m_list.Keys[m_list.Keys.Count - 1]].value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -265,7 +273,7 @@ namespace Boare.Lib.Vsq { | ||||
|         public void print( StreamWriter writer ) { | ||||
|             bool first = true; | ||||
|             foreach ( int key in m_list.Keys ) { | ||||
|                 int val = m_list[key]; | ||||
|                 int val = m_list[key].value; | ||||
|                 if ( first ) { | ||||
|                     writer.WriteLine( key + "=" + val ); | ||||
|                     first = false; | ||||
| @ -287,7 +295,7 @@ namespace Boare.Lib.Vsq { | ||||
|                         writer.writeLine( header ); | ||||
|                         first = false; | ||||
|                     } | ||||
|                     int val = m_list[key]; | ||||
|                     int val = m_list[key].value; | ||||
|                     writer.writeLine( key + "=" + val ); | ||||
|                 } | ||||
|             } | ||||
| @ -304,7 +312,9 @@ namespace Boare.Lib.Vsq { | ||||
|                 string[] spl = last_line.Split( new char[] { '=' } ); | ||||
|                 int i1 = int.Parse( spl[0] ); | ||||
|                 int i2 = int.Parse( spl[1] ); | ||||
|                 m_list.Add( i1, i2 ); | ||||
|                 VsqBPPair v = new VsqBPPair( i2, m_max_id + 1 ); | ||||
|                 m_max_id++; | ||||
|                 m_list.Add( i1, v ); | ||||
|                 if ( reader.peek() < 0 ) { | ||||
|                     break; | ||||
|                 } else { | ||||
|  | ||||
							
								
								
									
										15
									
								
								trunk/Boare.Lib.Vsq/VsqBPPair.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								trunk/Boare.Lib.Vsq/VsqBPPair.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| using System; | ||||
| 
 | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     public struct VsqBPPair { | ||||
|         public int value; | ||||
|         public int id; | ||||
| 
 | ||||
|         public VsqBPPair( int value_, int id_ ) { | ||||
|             value = value_; | ||||
|             id = id_; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -32,12 +32,29 @@ namespace Boare.Lib.Vsq { | ||||
|             m_ids = new List<int>(); | ||||
|         } | ||||
| 
 | ||||
|         public VsqEvent findFromID( int internal_id ) { | ||||
|             foreach ( VsqEvent item in Events ) { | ||||
|                 if ( item.InternalID == internal_id ) { | ||||
|                     return item; | ||||
|                 } | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public void setForID( int internal_id, VsqEvent value ) { | ||||
|             int c = Events.Count; | ||||
|             for ( int i = 0; i < c; i++ ) { | ||||
|                 if ( Events[i].InternalID == internal_id ) { | ||||
|                     Events[i] = value; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void sort() { | ||||
|             lock ( this ) { | ||||
|                 Events.Sort(); | ||||
|                 for ( int i = 0; i < Events.Count; i++ ) { | ||||
|                     m_ids[i] = Events[i].InternalID; | ||||
|                 } | ||||
|                 updateIDList(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -105,6 +122,10 @@ namespace Boare.Lib.Vsq { | ||||
|                 for ( int i = 0; i < Events.Count; i++ ) { | ||||
|                     m_ids.Add( Events[i].InternalID ); | ||||
|                 } | ||||
|             } else { | ||||
|                 for ( int i = 0; i < Events.Count; i++ ) { | ||||
|                     m_ids[i] = Events[i].InternalID; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -57,7 +57,8 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <param name="order"></param> | ||||
|         public void speedingUp( double order ) { | ||||
|             lock ( TempoTable ) { | ||||
|                 for ( int i = 0; i < TempoTable.Count; i++ ) { | ||||
|                 int c = TempoTable.Count; | ||||
|                 for ( int i = 0; i < c; i++ ) { | ||||
|                     TempoTable[i].Tempo = (int)(TempoTable[i].Tempo / order); | ||||
|                 } | ||||
|             } | ||||
| @ -116,7 +117,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 int new_clock = (int)command.Args[2]; | ||||
| 
 | ||||
|                 int index = -1; | ||||
|                 for ( int i = 0; i < TempoTable.Count; i++ ) { | ||||
|                 int c = TempoTable.Count; | ||||
|                 for ( int i = 0; i < c; i++ ) { | ||||
|                     if ( TempoTable[i].Clock == clock ) { | ||||
|                         index = i; | ||||
|                         break; | ||||
| @ -141,7 +143,8 @@ namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|                 // 編集領域を更新 | ||||
|                 int affected_clock = Math.Min( clock, new_clock ); | ||||
|                 for ( int i = 1; i < Track.Count; i++ ) { | ||||
|                 c = Track.Count; | ||||
|                 for ( int i = 1; i < c; i++ ) { | ||||
|                     if ( affected_clock < Track[i].getEditedStart() ) { | ||||
|                         Track[i].setEditedStart( affected_clock ); | ||||
|                     } | ||||
| @ -160,7 +163,8 @@ namespace Boare.Lib.Vsq { | ||||
|                     int index = -1; | ||||
|                     affected_clock = Math.Min( affected_clock, clocks[i] ); | ||||
|                     affected_clock = Math.Min( affected_clock, new_clocks[i] ); | ||||
|                     for ( int j = 0; j < TempoTable.Count; j++ ) { | ||||
|                     int tempo_table_count = TempoTable.Count; | ||||
|                     for ( int j = 0; j < tempo_table_count; j++ ) { | ||||
|                         if ( TempoTable[j].Clock == clocks[i] ) { | ||||
|                             index = j; | ||||
|                             break; | ||||
| @ -181,7 +185,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 } | ||||
|                 updateTempoInfo(); | ||||
|                 updateTotalClocks(); | ||||
|                 for ( int i = 1; i < Track.Count; i++ ) { | ||||
|                 int track_count = Track.Count; | ||||
|                 for ( int i = 1; i < track_count; i++ ) { | ||||
|                     if ( affected_clock < Track[i].getEditedStart() ) { | ||||
|                         Track[i].setEditedStart( affected_clock ); | ||||
|                     } | ||||
| @ -196,7 +201,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 int denominator = (int)command.Args[2]; | ||||
|                 int new_barcount = (int)command.Args[3]; | ||||
|                 int index = -1; | ||||
|                 for ( int i = 0; i < TimesigTable.Count; i++ ) { | ||||
|                 int timesig_table_count = TimesigTable.Count; | ||||
|                 for ( int i = 0; i < timesig_table_count; i++ ) { | ||||
|                     if ( barcount == TimesigTable[i].BarCount ) { | ||||
|                         index = i; | ||||
|                         break; | ||||
| @ -232,7 +238,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 for ( int i = 0; i < barcounts.Length; i++ ) { | ||||
|                     int index = -1; | ||||
|                     // すでに拍子が登録されているかどうかを検査 | ||||
|                     for ( int j = 0; j < TimesigTable.Count; j++ ) { | ||||
|                     int timesig_table_count = TimesigTable.Count; | ||||
|                     for ( int j = 0; j < timesig_table_count; j++ ) { | ||||
|                         if ( TimesigTable[j].BarCount == barcounts[i] ) { | ||||
|                             index = j; | ||||
|                             break; | ||||
| @ -265,19 +272,22 @@ namespace Boare.Lib.Vsq { | ||||
|                 VsqFile vsq = (VsqFile)command.Args[0]; | ||||
|                 VsqFile inv = (VsqFile)this.Clone(); | ||||
|                 Track.Clear(); | ||||
|                 for ( int i = 0; i < vsq.Track.Count; i++ ) { | ||||
|                 int track_count = vsq.Track.Count; | ||||
|                 for ( int i = 0; i < track_count; i++ ) { | ||||
|                     Track.Add( (VsqTrack)vsq.Track[i].Clone() ); | ||||
|                 } | ||||
| #if USE_TEMPO_LIST | ||||
|                 m_tempo_table = (TempoTable)vsq.m_tempo_table.Clone(); | ||||
| #else | ||||
|                 TempoTable.Clear(); | ||||
|                 for ( int i = 0; i < vsq.TempoTable.Count; i++ ) { | ||||
|                 int tempo_table_count = vsq.TempoTable.Count; | ||||
|                 for ( int i = 0; i < tempo_table_count; i++ ) { | ||||
|                     TempoTable.Add( (TempoTableEntry)vsq.TempoTable[i].Clone() ); | ||||
|                 } | ||||
| #endif | ||||
|                 TimesigTable.Clear(); | ||||
|                 for ( int i = 0; i < vsq.TimesigTable.Count; i++ ) { | ||||
|                 int timesig_table_count = vsq.TimesigTable.Count; | ||||
|                 for ( int i = 0; i < timesig_table_count; i++ ) { | ||||
|                     TimesigTable.Add( (TimeSigTableEntry)vsq.TimesigTable[i].Clone() ); | ||||
|                 } | ||||
|                 m_tpq = vsq.m_tpq; | ||||
| @ -285,7 +295,6 @@ namespace Boare.Lib.Vsq { | ||||
|                 m_base_tempo = vsq.m_base_tempo; | ||||
|                 Master = (VsqMaster)vsq.Master.Clone(); | ||||
|                 Mixer = (VsqMixer)vsq.Mixer.Clone(); | ||||
|                 //m_premeasure_clocks = vsq.m_premeasure_clocks; | ||||
|                 updateTotalClocks(); | ||||
|                 return VsqCommand.generateCommandReplace( inv ); | ||||
|                 #endregion | ||||
| @ -293,11 +302,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 #region EventAdd | ||||
|                 int track = (int)command.Args[0]; | ||||
|                 VsqEvent item = (VsqEvent)command.Args[1]; | ||||
|                 //int key = this.Tracks[track].GetNextId( 0 ); | ||||
|                 //item.InternalID = key; | ||||
|                 Track[track].addEvent( item ); | ||||
|                 VsqCommand ret = VsqCommand.generateCommandEventDelete( track, item.InternalID ); | ||||
|                 //this.Tracks[track].Events.Sort(); | ||||
|                 updateTotalClocks(); | ||||
|                 if ( item.Clock < Track[track].getEditedStart() ) { | ||||
|                     Track[track].setEditedStart( item.Clock ); | ||||
| @ -305,6 +311,7 @@ namespace Boare.Lib.Vsq { | ||||
|                 if ( Track[track].getEditedEnd() < item.Clock + item.ID.Length ) { | ||||
|                     Track[track].setEditedEnd( item.Clock + item.ID.Length ); | ||||
|                 } | ||||
|                 Track[track].sortEvent(); | ||||
|                 return ret; | ||||
|                 #endregion | ||||
|             } else if ( type == VsqCommandType.EventAddRange ) { | ||||
| @ -321,8 +328,6 @@ namespace Boare.Lib.Vsq { | ||||
|                     VsqEvent item = (VsqEvent)items[i].Clone(); | ||||
|                     min_clock = Math.Min( min_clock, item.Clock ); | ||||
|                     max_clock = Math.Max( max_clock, item.Clock + item.ID.Length ); | ||||
|                     //int key = Tracks[track].GetNextId( i ); | ||||
|                     //item.InternalID = key; | ||||
| #if DEBUG | ||||
|                     Console.Write( "        i=" + i + "; item.InternalID=" + item.InternalID ); | ||||
| #endif | ||||
| @ -332,7 +337,6 @@ namespace Boare.Lib.Vsq { | ||||
|                     Console.WriteLine( " => " + item.InternalID ); | ||||
| #endif | ||||
|                 } | ||||
|                 //Tracks[track].Events.Sort(); | ||||
|                 updateTotalClocks(); | ||||
|                 if ( min_clock < Track[track].getEditedStart() ) { | ||||
|                     Track[track].setEditedStart( min_clock ); | ||||
| @ -340,6 +344,7 @@ namespace Boare.Lib.Vsq { | ||||
|                 if ( Track[track].getEditedEnd() < max_clock ) { | ||||
|                     Track[track].setEditedEnd( max_clock ); | ||||
|                 } | ||||
|                 Track[track].sortEvent(); | ||||
|                 return VsqCommand.generateCommandEventDeleteRange( track, inv_ids.ToArray() ); | ||||
|                 #endregion | ||||
|             } else if ( type == VsqCommandType.EventDelete ) { | ||||
| @ -347,23 +352,25 @@ namespace Boare.Lib.Vsq { | ||||
|                 int internal_id = (int)command.Args[0]; | ||||
|                 int track = (int)command.Args[1]; | ||||
|                 VsqEvent[] original = new VsqEvent[1]; | ||||
|                 for ( Iterator itr = Track[track].getEventIterator(); itr.hasNext(); ) { | ||||
|                 VsqTrack target = Track[track]; | ||||
|                 for ( Iterator itr = target.getEventIterator(); itr.hasNext(); ) { | ||||
|                     VsqEvent item = (VsqEvent)itr.next(); | ||||
|                     if ( item.InternalID == internal_id ) { | ||||
|                         original[0] = (VsqEvent)item.Clone(); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if ( original[0].Clock < Track[track].getEditedStart() ) { | ||||
|                     Track[track].setEditedStart( original[0].Clock ); | ||||
|                 if ( original[0].Clock < target.getEditedStart() ) { | ||||
|                     target.setEditedStart( original[0].Clock ); | ||||
|                 } | ||||
|                 if ( Track[track].getEditedEnd() < original[0].Clock + original[0].ID.Length ) { | ||||
|                     Track[track].setEditedEnd( original[0].Clock + original[0].ID.Length ); | ||||
|                 if ( target.getEditedEnd() < original[0].Clock + original[0].ID.Length ) { | ||||
|                     target.setEditedEnd( original[0].Clock + original[0].ID.Length ); | ||||
|                 } | ||||
|                 VsqCommand ret = VsqCommand.generateCommandEventAddRange( track, original ); | ||||
|                 for ( int i = 0; i < this.Track[track].getEventCount(); i++ ) { | ||||
|                     if ( this.Track[track].getEvent( i ).InternalID == internal_id ) { | ||||
|                         Track[track].removeEvent( i ); | ||||
|                 int count = target.getEventCount(); | ||||
|                 for ( int i = 0; i < count; i++ ) { | ||||
|                     if ( target.getEvent( i ).InternalID == internal_id ) { | ||||
|                         target.removeEvent( i ); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
| @ -377,20 +384,22 @@ namespace Boare.Lib.Vsq { | ||||
|                 List<VsqEvent> inv = new List<VsqEvent>(); | ||||
|                 int min_clock = int.MaxValue; | ||||
|                 int max_clock = int.MinValue; | ||||
|                 VsqTrack target = this.Track[track]; | ||||
|                 for ( int j = 0; j < internal_ids.Length; j++ ) { | ||||
|                     for ( int i = 0; i < Track[track].getEventCount(); i++ ) { | ||||
|                         if ( internal_ids[j] == Track[track].getEvent( i ).InternalID ) { | ||||
|                             inv.Add( (VsqEvent)Track[track].getEvent( i ).Clone() ); | ||||
|                             min_clock = Math.Min( min_clock, Track[track].getEvent( i ).Clock ); | ||||
|                             max_clock = Math.Max( max_clock, Track[track].getEvent( i ).Clock + Track[track].getEvent( i ).ID.Length ); | ||||
|                             Track[track].removeEvent( i ); | ||||
|                     for ( int i = 0; i < target.getEventCount(); i++ ) { | ||||
|                         VsqEvent item = target.getEvent( i ); | ||||
|                         if ( internal_ids[j] == item.InternalID ) { | ||||
|                             inv.Add( (VsqEvent)item.Clone() ); | ||||
|                             min_clock = Math.Min( min_clock, item.Clock ); | ||||
|                             max_clock = Math.Max( max_clock, item.Clock + item.ID.Length ); | ||||
|                             target.removeEvent( i ); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 updateTotalClocks(); | ||||
|                 Track[track].setEditedStart( min_clock ); | ||||
|                 Track[track].setEditedEnd( max_clock ); | ||||
|                 target.setEditedStart( min_clock ); | ||||
|                 target.setEditedEnd( max_clock ); | ||||
|                 return VsqCommand.generateCommandEventAddRange( track, inv.ToArray() ); | ||||
|                 #endregion | ||||
|             } else if ( type == VsqCommandType.EventChangeClock ) { | ||||
| @ -398,16 +407,16 @@ namespace Boare.Lib.Vsq { | ||||
|                 int track = (int)command.Args[0]; | ||||
|                 int internal_id = (int)command.Args[1]; | ||||
|                 int value = (int)command.Args[2]; | ||||
|                 for ( Iterator itr = Track[track].getEventIterator(); itr.hasNext(); ) { | ||||
|                 VsqTrack target = this.Track[track]; | ||||
|                 for ( Iterator itr = target.getEventIterator(); itr.hasNext(); ) { | ||||
|                     VsqEvent item = (VsqEvent)itr.next(); | ||||
|                     if ( item.InternalID == internal_id ) { | ||||
|                         VsqCommand ret = VsqCommand.generateCommandEventChangeClock( track, internal_id, item.Clock ); | ||||
|                         int min = Math.Min( item.Clock, value ); | ||||
|                         int max = Math.Max( item.Clock + item.ID.Length, value + item.ID.Length ); | ||||
|                         Track[track].setEditedStart( min ); | ||||
|                         Track[track].setEditedEnd( max ); | ||||
|                         target.setEditedStart( min ); | ||||
|                         target.setEditedEnd( max ); | ||||
|                         item.Clock = value; | ||||
|                         //this.Tracks[track].Events.Sort(); | ||||
|                         updateTotalClocks(); | ||||
|                         return ret; | ||||
|                     } | ||||
| @ -421,7 +430,8 @@ namespace Boare.Lib.Vsq { | ||||
|                 string phrase = (string)command.Args[2]; | ||||
|                 string phonetic_symbol = (string)command.Args[3]; | ||||
|                 bool protect_symbol = (bool)command.Args[4]; | ||||
|                 for ( Iterator itr = Track[track].getEventIterator(); itr.hasNext(); ) { | ||||
|                 VsqTrack target = this.Track[track]; | ||||
|                 for ( Iterator itr = target.getEventIterator(); itr.hasNext(); ) { | ||||
|                     VsqEvent item = (VsqEvent)itr.next(); | ||||
|                     if ( item.InternalID == internal_id ) { | ||||
|                         if ( item.ID.type == VsqIDType.Anote ) { | ||||
| @ -429,8 +439,8 @@ namespace Boare.Lib.Vsq { | ||||
|                             item.ID.LyricHandle.L0.Phrase = phrase; | ||||
|                             item.ID.LyricHandle.L0.setPhoneticSymbol( phonetic_symbol ); | ||||
|                             item.ID.LyricHandle.L0.PhoneticSymbolProtected = protect_symbol; | ||||
|                             Track[track].setEditedStart( item.Clock ); | ||||
|                             Track[track].setEditedEnd( item.Clock + item.ID.Length ); | ||||
|                             target.setEditedStart( item.Clock ); | ||||
|                             target.setEditedEnd( item.Clock + item.ID.Length ); | ||||
|                             updateTotalClocks(); | ||||
|                             return ret; | ||||
|                         } | ||||
| @ -443,14 +453,15 @@ namespace Boare.Lib.Vsq { | ||||
|                 int track = (int)command.Args[0]; | ||||
|                 int internal_id = (int)command.Args[1]; | ||||
|                 int note = (int)command.Args[2]; | ||||
|                 for ( Iterator itr = Track[track].getEventIterator(); itr.hasNext(); ) { | ||||
|                 VsqTrack target = this.Track[track]; | ||||
|                 for ( Iterator itr = target.getEventIterator(); itr.hasNext(); ) { | ||||
|                     VsqEvent item = (VsqEvent)itr.next(); | ||||
|                     if ( item.InternalID == internal_id ) { | ||||
|                         VsqCommand ret = VsqCommand.generateCommandEventChangeNote( track, internal_id, item.ID.Note ); | ||||
|                         item.ID.Note = note; | ||||
|                         updateTotalClocks(); | ||||
|                         Track[track].setEditedStart( item.Clock ); | ||||
|                         Track[track].setEditedEnd( item.Clock + item.ID.Length ); | ||||
|                         target.setEditedStart( item.Clock ); | ||||
|                         target.setEditedEnd( item.Clock + item.ID.Length ); | ||||
|                         return ret; | ||||
|                     } | ||||
|                 } | ||||
| @ -462,17 +473,17 @@ namespace Boare.Lib.Vsq { | ||||
|                 int internal_id = (int)command.Args[1]; | ||||
|                 int clock = (int)command.Args[2]; | ||||
|                 int note = (int)command.Args[3]; | ||||
|                 for ( Iterator itr = Track[track].getEventIterator(); itr.hasNext(); ) { | ||||
|                 VsqTrack target = this.Track[track]; | ||||
|                 for ( Iterator itr = target.getEventIterator(); itr.hasNext(); ) { | ||||
|                     VsqEvent item = (VsqEvent)itr.next(); | ||||
|                     if ( item.InternalID == internal_id ) { | ||||
|                         VsqCommand ret = VsqCommand.generateCommandEventChangeClockAndNote( track, internal_id, item.Clock, item.ID.Note ); | ||||
|                         int min = Math.Min( item.Clock, clock ); | ||||
|                         int max = Math.Max( item.Clock + item.ID.Length, clock + item.ID.Length ); | ||||
|                         Track[track].setEditedStart( min ); | ||||
|                         Track[track].setEditedEnd( max ); | ||||
|                         target.setEditedStart( min ); | ||||
|                         target.setEditedEnd( max ); | ||||
|                         item.Clock = clock; | ||||
|                         item.ID.Note = note; | ||||
|                         //this.Tracks[track].Events.Sort(); | ||||
|                         updateTotalClocks(); | ||||
|                         return ret; | ||||
|                     } | ||||
| @ -484,7 +495,6 @@ namespace Boare.Lib.Vsq { | ||||
|                 int track = (int)command.Args[0]; | ||||
|                 string curve = (string)command.Args[1]; | ||||
|                 List<BPPair> com = (List<BPPair>)command.Args[2]; | ||||
| 
 | ||||
|                 VsqCommand inv = null; | ||||
|                 List<BPPair> edit = new List<BPPair>(); | ||||
|                 if ( com != null ) { | ||||
| @ -772,6 +782,7 @@ namespace Boare.Lib.Vsq { | ||||
|                         Track[track].setEditedEnd( max ); | ||||
|                         item.ID.Length = new_length; | ||||
|                         item.Clock = new_clock; | ||||
|                         Track[track].sortEvent(); | ||||
|                         updateTotalClocks(); | ||||
|                         return ret; | ||||
|                     } | ||||
| @ -880,6 +891,7 @@ namespace Boare.Lib.Vsq { | ||||
|                         item.Clock = new_clock; | ||||
|                         Track[track].setEditedStart( min ); | ||||
|                         Track[track].setEditedEnd( max ); | ||||
|                         Track[track].sortEvent(); | ||||
|                         updateTotalClocks(); | ||||
|                         return ret; | ||||
|                     } | ||||
| @ -911,6 +923,7 @@ namespace Boare.Lib.Vsq { | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 Track[track].sortEvent(); | ||||
|                 updateTotalClocks(); | ||||
|                 return VsqCommand.generateCommandEventChangeClockAndIDContaintsRange( | ||||
|                     track, | ||||
| @ -963,6 +976,8 @@ namespace Boare.Lib.Vsq { | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 Track[track].sortEvent(); | ||||
|                 updateTotalClocks(); | ||||
|                 return ret; | ||||
|                 #endregion | ||||
|             } else if ( type == VsqCommandType.EventReplaceRange ) { | ||||
| @ -982,6 +997,8 @@ namespace Boare.Lib.Vsq { | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 Track[track].sortEvent(); | ||||
|                 updateTotalClocks(); | ||||
|                 ret = VsqCommand.generateCommandEventReplaceRange( track, reverse ); | ||||
|                 return ret; | ||||
|                 #endregion | ||||
| @ -1002,6 +1019,7 @@ namespace Boare.Lib.Vsq { | ||||
|             // テンポ情報の削除、シフト | ||||
|             bool changed = true; | ||||
|             List<TempoTableEntry> buf = new List<TempoTableEntry>( TempoTable ); | ||||
|             int tempo_at_clock_start = getTempoAt( clock_start ); | ||||
|             int tempo_at_clock_end = getTempoAt( clock_end ); | ||||
|             TempoTable.Clear(); | ||||
|             bool just_on_clock_end_added = false; | ||||
| @ -1015,15 +1033,17 @@ namespace Boare.Lib.Vsq { | ||||
|                         TempoTable.Add( tte ); | ||||
|                         just_on_clock_end_added = true; | ||||
|                     } else { | ||||
|                         if ( !just_on_clock_end_added ) { | ||||
|                             TempoTable.Add( new TempoTableEntry( clock_start, tempo_at_clock_end, 0.0 ) ); | ||||
|                             just_on_clock_end_added = true; | ||||
|                         if ( tempo_at_clock_start != tempo_at_clock_end ) { | ||||
|                             if ( !just_on_clock_end_added ) { | ||||
|                                 TempoTable.Add( new TempoTableEntry( clock_start, tempo_at_clock_end, 0.0 ) ); | ||||
|                                 just_on_clock_end_added = true; | ||||
|                             } | ||||
|                         } | ||||
|                         TempoTable.Add( tte ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if ( !just_on_clock_end_added ) { | ||||
|             if ( tempo_at_clock_start != tempo_at_clock_end && !just_on_clock_end_added ) { | ||||
|                 TempoTable.Add( new TempoTableEntry( clock_start, tempo_at_clock_end, 0.0 ) ); | ||||
|             } | ||||
|             updateTempoInfo(); | ||||
| @ -1312,11 +1332,13 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <param name="clock"></param> | ||||
|         /// <returns></returns> | ||||
|         public double getSecFromClock( double clock ) { | ||||
|             for ( int i = TempoTable.Count - 1; i >= 0; i-- ) { | ||||
|                 if ( TempoTable[i].Clock < clock ) { | ||||
|                     double init = TempoTable[i].Time; | ||||
|                     double dclock = clock - TempoTable[i].Clock; | ||||
|                     double sec_per_clock1 = TempoTable[i].Tempo * 1e-6 / 480.0; | ||||
|             int c = TempoTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 TempoTableEntry item = TempoTable[i]; | ||||
|                 if ( item.Clock < clock ) { | ||||
|                     double init = item.Time; | ||||
|                     double dclock = clock - item.Clock; | ||||
|                     double sec_per_clock1 = item.Tempo * 1e-6 / 480.0; | ||||
|                     return init + dclock * sec_per_clock1; | ||||
|                 } | ||||
|             } | ||||
| @ -1338,18 +1360,20 @@ namespace Boare.Lib.Vsq { | ||||
|             int tempo = m_base_tempo; | ||||
|             double base_clock = 0; | ||||
|             double base_time = 0f; | ||||
|             if ( TempoTable.Count == 0 ) { | ||||
|             int c = TempoTable.Count; | ||||
|             if ( c == 0 ) { | ||||
|                 tempo = m_base_tempo; | ||||
|                 base_clock = 0; | ||||
|                 base_time = 0f; | ||||
|             } else if ( TempoTable.Count == 1 ) { | ||||
|             } else if ( c == 1 ) { | ||||
|                 tempo = TempoTable[0].Tempo; | ||||
|                 base_clock = TempoTable[0].Clock; | ||||
|                 base_time = TempoTable[0].Time; | ||||
|             } else { | ||||
|                 for ( int i = TempoTable.Count - 1; i >= 0; i-- ) { | ||||
|                     if ( TempoTable[i].Time < time ) { | ||||
|                         return TempoTable[i].Clock + (time - TempoTable[i].Time) * m_tpq * 1000000.0 / TempoTable[i].Tempo; | ||||
|                 for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                     TempoTableEntry item = TempoTable[i]; | ||||
|                     if ( item.Time < time ) { | ||||
|                         return item.Clock + (time - item.Time) * m_tpq * 1000000.0 / item.Tempo; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -1366,7 +1390,8 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <param name="denominator"></param> | ||||
|         public void getTimesigAt( int clock, out int numerator, out int denominator ) { | ||||
|             int index = 0; | ||||
|             for ( int i = TimesigTable.Count - 1; i >= 0; i-- ) { | ||||
|             int c = TimesigTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 index = i; | ||||
|                 if ( TimesigTable[i].Clock <= clock ) { | ||||
|                     break; | ||||
| @ -1378,17 +1403,19 @@ namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|         public void getTimesigAt( int clock, out int numerator, out int denominator, out int bar_count ) { | ||||
|             int index = 0; | ||||
|             for ( int i = TimesigTable.Count - 1; i >= 0; i-- ) { | ||||
|             int c = TimesigTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 index = i; | ||||
|                 if ( TimesigTable[i].Clock <= clock ) { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             numerator = TimesigTable[index].Numerator; | ||||
|             denominator = TimesigTable[index].Denominator; | ||||
|             int diff = clock - TimesigTable[index].Clock; | ||||
|             TimeSigTableEntry item = TimesigTable[index]; | ||||
|             numerator = item.Numerator; | ||||
|             denominator = item.Denominator; | ||||
|             int diff = clock - item.Clock; | ||||
|             int clock_per_bar = 480 * 4 / denominator * numerator; | ||||
|             bar_count = TimesigTable[index].BarCount + diff / clock_per_bar; | ||||
|             bar_count = item.BarCount + diff / clock_per_bar; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @ -1398,7 +1425,8 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <returns></returns> | ||||
|         public int getTempoAt( int clock ) { | ||||
|             int index = 0; | ||||
|             for ( int i = TempoTable.Count - 1; i >= 0; i-- ) { | ||||
|             int c = TempoTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 index = i; | ||||
|                 if ( TempoTable[i].Clock <= clock ) { | ||||
|                     break; | ||||
| @ -1414,16 +1442,18 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <returns></returns> | ||||
|         public int getClockFromBarCount( int bar_count ) { | ||||
|             int index = 0; | ||||
|             for ( int i = TimesigTable.Count - 1; i >= 0; i-- ) { | ||||
|             int c = TimesigTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 index = i; | ||||
|                 if ( TimesigTable[i].BarCount <= bar_count ) { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             int numerator = TimesigTable[index].Numerator; | ||||
|             int denominator = TimesigTable[index].Denominator; | ||||
|             int init_clock = TimesigTable[index].Clock; | ||||
|             int init_bar_count = TimesigTable[index].BarCount; | ||||
|             TimeSigTableEntry item = TimesigTable[index]; | ||||
|             int numerator = item.Numerator; | ||||
|             int denominator = item.Denominator; | ||||
|             int init_clock = item.Clock; | ||||
|             int init_bar_count = item.BarCount; | ||||
|             int clock_per_bar = numerator * 480 * 4 / denominator; | ||||
|             return init_clock + (bar_count - init_bar_count) * clock_per_bar; | ||||
|         } | ||||
| @ -1435,7 +1465,8 @@ namespace Boare.Lib.Vsq { | ||||
|         /// <returns></returns> | ||||
|         public int getBarCountFromClock( int clock ) { | ||||
|             int index = 0; | ||||
|             for ( int i = TimesigTable.Count - 1; i >= 0; i-- ) { | ||||
|             int c = TimesigTable.Count; | ||||
|             for ( int i = c - 1; i >= 0; i-- ) { | ||||
|                 index = i; | ||||
|                 if ( TimesigTable[i].Clock <= clock ) { | ||||
|                     break; | ||||
| @ -1569,15 +1600,15 @@ namespace Boare.Lib.Vsq { | ||||
|                 prev_time = 0.0; | ||||
|                 int count = -1; | ||||
|                 for ( int j = 0; j < midi_event.Count; j++ ) { | ||||
|                     if ( midi_event[j].FirstByte == 0xff && midi_event[j].Data.Length >= 4 && midi_event[j].Data[0] == 0x51 ) { | ||||
|                     if ( midi_event[j].firstByte == 0xff && midi_event[j].data.Length >= 4 && midi_event[j].data[0] == 0x51 ) { | ||||
|                         count++; | ||||
|                         if ( count == 0 && midi_event[j].Clock != 0 ) { | ||||
|                         if ( count == 0 && midi_event[j].clock != 0 ) { | ||||
|                             TempoTable.Add( new TempoTableEntry( 0, 500000, 0.0 ) ); | ||||
|                             m_base_tempo = 500000; | ||||
|                             prev_tempo = 500000; | ||||
|                         } | ||||
|                         int current_tempo = midi_event[j].Data[1] << 16 | midi_event[j].Data[2] << 8 | midi_event[j].Data[3]; | ||||
|                         int current_index = (int)midi_event[j].Clock; | ||||
|                         int current_tempo = midi_event[j].data[1] << 16 | midi_event[j].data[2] << 8 | midi_event[j].data[3]; | ||||
|                         int current_index = (int)midi_event[j].clock; | ||||
|                         thistime = prev_time + (double)(prev_tempo) * (double)(current_index - prev_index) / (m_tpq * 1000000.0); | ||||
|                         TempoTable.Add( new TempoTableEntry( current_index, current_tempo, thistime ) ); | ||||
|                         prev_tempo = current_tempo; | ||||
| @ -1598,11 +1629,11 @@ namespace Boare.Lib.Vsq { | ||||
|                 //m_timesig_table.Add( new TimeSigTableEntry( 0, numer, dnomi, 0 ) ); | ||||
|                 count = -1; | ||||
|                 for ( int j = 0; j < midi_event.Count; j++ ) { | ||||
|                     if ( midi_event[j].FirstByte == 0xff && midi_event[j].Data.Length >= 5 && midi_event[j].Data[0] == 0x58 ) { | ||||
|                     if ( midi_event[j].firstByte == 0xff && midi_event[j].data.Length >= 5 && midi_event[j].data[0] == 0x58 ) { | ||||
|                         count++; | ||||
|                         numer = midi_event[j].Data[1]; | ||||
|                         numer = midi_event[j].data[1]; | ||||
|                         dnomi = 1; | ||||
|                         for ( int i = 0; i < midi_event[j].Data[2]; i++ ) { | ||||
|                         for ( int i = 0; i < midi_event[j].data[2]; i++ ) { | ||||
|                             dnomi = dnomi * 2; | ||||
|                         } | ||||
|                         if ( count == 0 ){ | ||||
| @ -1610,11 +1641,11 @@ namespace Boare.Lib.Vsq { | ||||
|                             int denominator = 4; | ||||
|                             int clock = 0; | ||||
|                             int bar_count = 0; | ||||
|                             if ( midi_event[j].Clock == 0 ) { | ||||
|                             if ( midi_event[j].clock == 0 ) { | ||||
|                                 TimesigTable.Add( new TimeSigTableEntry( 0, numer, dnomi, 0 ) ); | ||||
|                             } else { | ||||
|                                 TimesigTable.Add( new TimeSigTableEntry( 0, 4, 4, 0 ) ); | ||||
|                                 TimesigTable.Add( new TimeSigTableEntry( 0, numer, dnomi, (int)midi_event[j].Clock / (480 * 4) ) ); | ||||
|                                 TimesigTable.Add( new TimeSigTableEntry( 0, numer, dnomi, (int)midi_event[j].clock / (480 * 4) ) ); | ||||
|                                 count++; | ||||
|                             } | ||||
|                         } else { | ||||
| @ -1623,8 +1654,8 @@ namespace Boare.Lib.Vsq { | ||||
|                             int clock = TimesigTable[count - 1].Clock; | ||||
|                             int bar_count = TimesigTable[count - 1].BarCount; | ||||
|                             int dif = 480 * 4 / denominator * numerator;//1小節が何クロックか? | ||||
|                             bar_count += ((int)midi_event[j].Clock - clock) / dif; | ||||
|                             TimesigTable.Add( new TimeSigTableEntry( (int)midi_event[j].Clock, numer, dnomi, bar_count ) ); | ||||
|                             bar_count += ((int)midi_event[j].clock - clock) / dif; | ||||
|                             TimesigTable.Add( new TimeSigTableEntry( (int)midi_event[j].clock, numer, dnomi, bar_count ) ); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @ -1774,7 +1805,7 @@ namespace Boare.Lib.Vsq { | ||||
|         public List<MidiEvent> generateMetaTextEvent( int track ) { | ||||
|             string _NL = "" + (char)0x0a; | ||||
|             List<MidiEvent> ret = new List<MidiEvent>(); | ||||
|             using ( TextMemoryStream sr = new TextMemoryStream( FileAccess.ReadWrite ) ) { | ||||
|             using ( TextMemoryStream sr = new TextMemoryStream() ) { | ||||
|                 Track[track].printMetaText( sr, TotalClocks + 120, calculatePreMeasureInClock() ); | ||||
|                 sr.rewind(); | ||||
|                 int line_count = -1; | ||||
| @ -1793,12 +1824,12 @@ namespace Boare.Lib.Vsq { | ||||
|                             tmp = tmp.Substring( 127 ); | ||||
|                             line_char = work.ToCharArray(); | ||||
|                             MidiEvent add = new MidiEvent(); | ||||
|                             add.Clock = 0; | ||||
|                             add.FirstByte = 0xff; //ステータス メタ* | ||||
|                             add.Data = new byte[line_char.Length + 1]; | ||||
|                             add.Data[0] = 0x01; //メタテキスト | ||||
|                             add.clock = 0; | ||||
|                             add.firstByte = 0xff; //ステータス メタ* | ||||
|                             add.data = new byte[line_char.Length + 1]; | ||||
|                             add.data[0] = 0x01; //メタテキスト | ||||
|                             for ( int i = 0; i < line_char.Length; i++ ) { | ||||
|                                 add.Data[i + 1] = (byte)line_char[i]; | ||||
|                                 add.data[i + 1] = (byte)line_char[i]; | ||||
|                             } | ||||
|                             ret.Add( add ); | ||||
|                         } | ||||
| @ -1811,12 +1842,12 @@ namespace Boare.Lib.Vsq { | ||||
|                         tmp = tmp.Substring( 127 ); | ||||
|                         line_char = work.ToCharArray(); | ||||
|                         MidiEvent add = new MidiEvent(); | ||||
|                         add.Clock = 0; | ||||
|                         add.FirstByte = 0xff; | ||||
|                         add.Data = new byte[line_char.Length + 1]; | ||||
|                         add.Data[0] = 0x01; | ||||
|                         add.clock = 0; | ||||
|                         add.firstByte = 0xff; | ||||
|                         add.data = new byte[line_char.Length + 1]; | ||||
|                         add.data[0] = 0x01; | ||||
|                         for ( int i = 0; i < line_char.Length; i++ ) { | ||||
|                             add.Data[i + 1] = (byte)line_char[i]; | ||||
|                             add.data[i + 1] = (byte)line_char[i]; | ||||
|                         } | ||||
|                         ret.Add( add ); | ||||
|                         line_count++; | ||||
| @ -1824,11 +1855,11 @@ namespace Boare.Lib.Vsq { | ||||
|                     } | ||||
|                     line_char = tmp.ToCharArray(); | ||||
|                     MidiEvent add0 = new MidiEvent(); | ||||
|                     add0.FirstByte = 0xff; | ||||
|                     add0.Data = new byte[line_char.Length + 1]; | ||||
|                     add0.Data[0] = 0x01; | ||||
|                     add0.firstByte = 0xff; | ||||
|                     add0.data = new byte[line_char.Length + 1]; | ||||
|                     add0.data[0] = 0x01; | ||||
|                     for ( int i = 0; i < line_char.Length; i++ ) { | ||||
|                         add0.Data[i + 1] = (byte)line_char[i]; | ||||
|                         add0.data[i + 1] = (byte)line_char[i]; | ||||
|                     } | ||||
|                     ret.Add( add0 ); | ||||
|                 } | ||||
| @ -1859,20 +1890,14 @@ namespace Boare.Lib.Vsq { | ||||
|             List<MidiEvent> meta = vsq.generateMetaTextEvent( track ); | ||||
|             long lastclock = 0; | ||||
|             for ( int i = 0; i < meta.Count; i++ ) { | ||||
|                 writeFlexibleLengthUnsignedLong( fs, (ulong)(meta[i].Clock - lastclock) ); | ||||
|                 writeFlexibleLengthUnsignedLong( fs, (ulong)(meta[i].clock - lastclock) ); | ||||
|                 meta[i].writeData( fs ); | ||||
|                 lastclock = meta[i].Clock; | ||||
|                 lastclock = meta[i].clock; | ||||
|             } | ||||
| 
 | ||||
|             int last = 0; | ||||
|             VsqNrpn[] data = generateNRPN( vsq, track, msPreSend ); | ||||
|             NrpnData[] nrpns = VsqNrpn.convert( data ); | ||||
| #if DEBUG | ||||
|             bocoree.debug.push_log( "VsqFile.printTrack; nrpns" ); | ||||
|             for ( int i = 0; i < nrpns.Length; i++ ) { | ||||
|                 bocoree.debug.push_log( "    clock,parameter,value=" + nrpns[i].getClock() + "," + Convert.ToString( nrpns[i].getParameter(), 16 ) + "," + Convert.ToString( nrpns[i].Value, 16 ) ); | ||||
|             } | ||||
| #endif | ||||
|             for ( int i = 0; i < nrpns.Length; i++ ) { | ||||
|                 writeFlexibleLengthUnsignedLong( fs, (ulong)(nrpns[i].getClock() - last) ); | ||||
|                 fs.WriteByte( 0xb0 ); | ||||
| @ -1987,9 +2012,8 @@ namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|             int i = clock - vsq.getPresendClockAt( clock, msPreSend ); | ||||
|             VsqNrpn add = new VsqNrpn( i, (ushort)NRPN.CC_BS_VERSION_AND_DEVICE, 0x00, 0x00 ); | ||||
|             add.append( NRPN.CC_BS_DELAY, delay0, delay1 ); | ||||
|             add.append( NRPN.CC_BS_LANGUAGE_TYPE, (byte)ve.ID.IconHandle.Language ); | ||||
|             //add.append( NRPN.PC_VERSION_AND_DEVICE, 0x00, 0x00 ); | ||||
|             add.append( NRPN.CC_BS_DELAY, delay0, delay1, true ); | ||||
|             add.append( NRPN.CC_BS_LANGUAGE_TYPE, (byte)ve.ID.IconHandle.Language, true ); | ||||
|             add.append( NRPN.PC_VOICE_TYPE, (byte)ve.ID.IconHandle.Program ); | ||||
|             return new VsqNrpn[] { add }; | ||||
|         } | ||||
| @ -2019,24 +2043,24 @@ namespace Boare.Lib.Vsq { | ||||
|                 byte delay0, delay1; | ||||
|                 getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); | ||||
|                 add = new VsqNrpn( clock - vsq.getPresendClockAt( clock, msPreSend ), NRPN.CVM_NM_VERSION_AND_DEVICE, 0x00, 0x00 ); | ||||
|                 add.append( NRPN.CVM_NM_DELAY, delay0, delay1 ); | ||||
|                 add.append( NRPN.CVM_NM_NOTE_NUMBER, (byte)ve.ID.Note ); // Note number | ||||
|                 add.append( NRPN.CVM_NM_DELAY, delay0, delay1, true ); | ||||
|                 add.append( NRPN.CVM_NM_NOTE_NUMBER, (byte)ve.ID.Note, true ); // Note number | ||||
|             } else { | ||||
|                 add = new VsqNrpn( clock - vsq.getPresendClockAt( clock, msPreSend ), NRPN.CVM_NM_NOTE_NUMBER, (byte)ve.ID.Note ); // Note number | ||||
|             } | ||||
|             add.append( NRPN.CVM_NM_VELOCITY, (byte)ve.ID.Dynamics ); // Velocity | ||||
|             add.append( NRPN.CVM_NM_NOTE_DURATION, duration0, duration1 ); // Note duration | ||||
|             add.append( NRPN.CVM_NM_NOTE_LOCATION, note_loc ); // Note Location | ||||
|             add.append( NRPN.CVM_NM_VELOCITY, (byte)ve.ID.Dynamics, true ); // Velocity | ||||
|             add.append( NRPN.CVM_NM_NOTE_DURATION, duration0, duration1, true ); // Note duration | ||||
|             add.append( NRPN.CVM_NM_NOTE_LOCATION, note_loc, true ); // Note Location | ||||
| 
 | ||||
|             if ( ve.ID.VibratoHandle != null ) { | ||||
|                 add.append( NRPN.CVM_NM_INDEX_OF_VIBRATO_DB, 0x00, 0x00 ); | ||||
|                 add.append( NRPN.CVM_NM_INDEX_OF_VIBRATO_DB, 0x00, 0x00, true ); | ||||
|                 int vibrato_type = (int)VibratoTypeUtil.getVibratoTypeFromIconID( ve.ID.VibratoHandle.IconID ); | ||||
|                 int note_length = ve.ID.Length; | ||||
|                 int vibrato_delay = ve.ID.VibratoDelay; | ||||
|                 byte bVibratoDuration = (byte)((float)(note_length - vibrato_delay) / (float)note_length * 127); | ||||
|                 byte bVibratoDelay = (byte)(0x7f - bVibratoDuration); | ||||
|                 add.append( NRPN.CVM_NM_VIBRATO_CONFIG, (byte)vibrato_type, bVibratoDuration ); | ||||
|                 add.append( NRPN.CVM_NM_VIBRATO_DELAY, bVibratoDelay ); | ||||
|                 add.append( NRPN.CVM_NM_VIBRATO_CONFIG, (byte)vibrato_type, bVibratoDuration, true ); | ||||
|                 add.append( NRPN.CVM_NM_VIBRATO_DELAY, bVibratoDelay, true ); | ||||
|             } | ||||
| 
 | ||||
|             string[] spl = ve.ID.LyricHandle.L0.getPhoneticSymbolList(); | ||||
| @ -2046,23 +2070,23 @@ namespace Boare.Lib.Vsq { | ||||
|             } | ||||
|             char[] symbols = s.ToCharArray(); | ||||
|             if ( renderer.StartsWith( "DSB2" ) ) { | ||||
|                 add.append( 0x5011, (byte)0x01 );//TODO: 0x5011の意味は解析中 | ||||
|                 add.append( 0x5011, (byte)0x01, true );//TODO: 0x5011の意味は解析中 | ||||
|             } | ||||
|             add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_BYTES, (byte)symbols.Length );// 0x12(Number of phonetic symbols in bytes) | ||||
|             add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_BYTES, (byte)symbols.Length, true );// 0x12(Number of phonetic symbols in bytes) | ||||
|             int count = -1; | ||||
|             for ( int j = 0; j < spl.Length; j++ ) { | ||||
|                 char[] chars = spl[j].ToCharArray(); | ||||
|                 for ( int k = 0; k < chars.Length; k++ ) { | ||||
|                     count++; | ||||
|                     if ( k == 0 ) { | ||||
|                         add.append( (ushort)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k], (byte)ve.ID.LyricHandle.L0.getConsonantAdjustment()[j] ); // Phonetic symbol j | ||||
|                         add.append( (ushort)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k], (byte)ve.ID.LyricHandle.L0.getConsonantAdjustment()[j], true ); // Phonetic symbol j | ||||
|                     } else { | ||||
|                         add.append( (ushort)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k] ); // Phonetic symbol j | ||||
|                         add.append( (ushort)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k], true ); // Phonetic symbol j | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if ( !renderer.StartsWith( "DSB2" ) ) { | ||||
|                 add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_CONTINUATION, 0x7f ); // End of phonetic symbols | ||||
|                 add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_CONTINUATION, 0x7f, true ); // End of phonetic symbols | ||||
|             } | ||||
|             if ( renderer.StartsWith( "DSB3" ) ) { | ||||
|                 int v1mean = ve.ID.PMBendDepth * 60 / 100; | ||||
| @ -2074,18 +2098,19 @@ namespace Boare.Lib.Vsq { | ||||
|                 } | ||||
|                 int d1mean = (int)(0.3196 * ve.ID.PMBendLength + 8.0); | ||||
|                 int d2mean = (int)(0.92 * ve.ID.PMBendLength + 28.0); | ||||
|                 add.append( NRPN.CVM_NM_V1MEAN, (byte)v1mean );// 0x50(v1mean) | ||||
|                 add.append( NRPN.CVM_NM_D1MEAN, (byte)d1mean );// 0x51(d1mean) | ||||
|                 add.append( NRPN.CVM_NM_D1MEAN_FIRST_NOTE, 0x14 );// 0x52(d1meanFirstNote) | ||||
|                 add.append( NRPN.CVM_NM_D2MEAN, (byte)d2mean );// 0x53(d2mean) | ||||
|                 add.append( NRPN.CVM_NM_D4MEAN, 0x18 );// 0x54(d4mean) | ||||
|                 add.append( NRPN.CVM_NM_PMEAN_ONSET_FIRST_NOTE, 0x0a ); // 055(pMeanOnsetFirstNote) | ||||
|                 add.append( NRPN.CVM_NM_VMEAN_NOTE_TRNSITION, 0x0c ); // 0x56(vMeanNoteTransition) | ||||
|                 add.append( NRPN.CVM_NM_PMEAN_ENDING_NOTE, 0x0c );// 0x57(pMeanEndingNote) | ||||
|                 add.append( NRPN.CVM_NM_ADD_PORTAMENTO, (byte)ve.ID.PMbPortamentoUse );// 0x58(AddScoopToUpInternals&AddPortamentoToDownIntervals) | ||||
|                 add.append( NRPN.CVM_NM_CHANGE_AFTER_PEAK, 0x32 );// 0x59(changeAfterPeak) | ||||
|                 add.append( NRPN.CVM_NM_V1MEAN, (byte)v1mean, true );// 0x50(v1mean) | ||||
|                 add.append( NRPN.CVM_NM_D1MEAN, (byte)d1mean, true );// 0x51(d1mean) | ||||
|                 add.append( NRPN.CVM_NM_D1MEAN_FIRST_NOTE, 0x14, true );// 0x52(d1meanFirstNote) | ||||
|                 add.append( NRPN.CVM_NM_D2MEAN, (byte)d2mean, true );// 0x53(d2mean) | ||||
|                 add.append( NRPN.CVM_NM_D4MEAN, (byte)ve.ID.d4mean, true );// 0x54(d4mean) | ||||
|                 add.append( NRPN.CVM_NM_PMEAN_ONSET_FIRST_NOTE, (byte)ve.ID.pMeanOnsetFirstNote, true ); // 055(pMeanOnsetFirstNote) | ||||
|                 add.append( NRPN.CVM_NM_VMEAN_NOTE_TRNSITION, (byte)ve.ID.vMeanNoteTransition, true ); // 0x56(vMeanNoteTransition) | ||||
|                 add.append( NRPN.CVM_NM_PMEAN_ENDING_NOTE, (byte)ve.ID.pMeanEndingNote, true );// 0x57(pMeanEndingNote) | ||||
|                 add.append( NRPN.CVM_NM_ADD_PORTAMENTO, (byte)ve.ID.PMbPortamentoUse, true );// 0x58(AddScoopToUpInternals&AddPortamentoToDownIntervals) | ||||
|                 byte decay = (byte)(ve.ID.DEMdecGainRate / 100.0 * 0x64); | ||||
|                 add.append( NRPN.CVM_NM_CHANGE_AFTER_PEAK, decay, true );// 0x59(changeAfterPeak) | ||||
|                 byte accent = (byte)(0x64 * ve.ID.DEMaccent / 100.0); | ||||
|                 add.append( NRPN.CVM_NM_ACCENT, accent );// 0x5a(Accent) | ||||
|                 add.append( NRPN.CVM_NM_ACCENT, accent, true );// 0x5a(Accent) | ||||
|             } | ||||
|             if ( renderer.StartsWith( "UTU0" ) ) { | ||||
|                 // エンベロープ | ||||
| @ -2097,11 +2122,7 @@ namespace Boare.Lib.Vsq { | ||||
|                         env = new UstEnvelope(); | ||||
|                     } | ||||
|                     int[] vals = null; | ||||
|                     if ( env.Separator == "" ) { | ||||
|                         vals = new int[7]; | ||||
|                     } else { | ||||
|                         vals = new int[10]; | ||||
|                     } | ||||
|                     vals[0] = env.p1; | ||||
|                     vals[1] = env.p2; | ||||
|                     vals[2] = env.p3; | ||||
| @ -2109,11 +2130,9 @@ namespace Boare.Lib.Vsq { | ||||
|                     vals[4] = env.v2; | ||||
|                     vals[5] = env.v3; | ||||
|                     vals[6] = env.v4; | ||||
|                     if ( env.Separator != "" ) { | ||||
|                         vals[7] = env.p4; | ||||
|                         vals[8] = env.p5; | ||||
|                         vals[9] = env.v5; | ||||
|                     } | ||||
|                     vals[7] = env.p4; | ||||
|                     vals[8] = env.p5; | ||||
|                     vals[9] = env.v5; | ||||
|                     for ( int i = 0; i < vals.Length; i++ ) { | ||||
|                         //(value3.msb & 0xf) << 28 | (value2.msb & 0x7f) << 21 | (value2.lsb & 0x7f) << 14 | (value1.msb & 0x7f) << 7 | (value1.lsb & 0x7f) | ||||
|                         byte msb, lsb; | ||||
| @ -2165,7 +2184,7 @@ namespace Boare.Lib.Vsq { | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             add.append( NRPN.CVM_NM_NOTE_MESSAGE_CONTINUATION, 0x7f );// 0x7f(Note message continuation) | ||||
|             add.append( NRPN.CVM_NM_NOTE_MESSAGE_CONTINUATION, 0x7f, true );// 0x7f(Note message continuation) | ||||
|             return add; | ||||
|         } | ||||
| 
 | ||||
| @ -2395,8 +2414,8 @@ namespace Boare.Lib.Vsq { | ||||
|                                             NRPN.CC_VD_VERSION_AND_DEVICE, | ||||
|                                             0x00, | ||||
|                                             0x00 ); | ||||
|                 add2.append( NRPN.CC_VD_DELAY, delay0, delay1 ); | ||||
|                 add2.append( NRPN.CC_VD_VIBRATO_DEPTH, (byte)ve.ID.VibratoHandle.StartDepth ); | ||||
|                 add2.append( NRPN.CC_VD_DELAY, delay0, delay1, true ); | ||||
|                 add2.append( NRPN.CC_VD_VIBRATO_DEPTH, (byte)ve.ID.VibratoHandle.StartDepth, true ); | ||||
|                 add2.append( NRPN.CC_VR_VIBRATO_RATE, (byte)ve.ID.VibratoHandle.StartRate ); | ||||
|                 ret.Add( add2 ); | ||||
|                 int vlength = ve.ID.Length - ve.ID.VibratoDelay; | ||||
| @ -2456,7 +2475,7 @@ namespace Boare.Lib.Vsq { | ||||
|                             VsqNrpn add = new VsqNrpn( c, | ||||
|                                                        NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, | ||||
|                                                        lsb ); | ||||
|                             add.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vbpl.getElement( j ) ); | ||||
|                             add.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vbpl.getElement( j ), true ); | ||||
|                             res.Add( add ); | ||||
|                         } | ||||
|                     } | ||||
| @ -2565,11 +2584,11 @@ namespace Boare.Lib.Vsq { | ||||
|                 long last = 0; | ||||
|                 foreach ( MidiEvent me in events ) { | ||||
| #if DEBUG | ||||
|                     Console.WriteLine( "me.Clock=" + me.Clock ); | ||||
|                     Console.WriteLine( "me.Clock=" + me.clock ); | ||||
| #endif | ||||
|                     writeFlexibleLengthUnsignedLong( fs, (ulong)(me.Clock - last) ); | ||||
|                     writeFlexibleLengthUnsignedLong( fs, (ulong)(me.clock - last) ); | ||||
|                     me.writeData( fs ); | ||||
|                     last = me.Clock; | ||||
|                     last = me.clock; | ||||
|                 } | ||||
| 
 | ||||
|                 //WriteFlexibleLengthUnsignedLong( fs, (ulong)(last_clock + 120 - last) ); | ||||
|  | ||||
| @ -113,6 +113,10 @@ namespace Boare.Lib.Vsq { | ||||
|             DepthBP = new VibratoBPList(); | ||||
|         } | ||||
| 
 | ||||
|         /*public static VibratoHandle[] fromVED( string ved_file, int original ){ | ||||
|              | ||||
|         }*/ | ||||
| 
 | ||||
|         public object Clone() { | ||||
|             VibratoHandle result = new VibratoHandle(); | ||||
|             result.Index = Index; | ||||
|  | ||||
| @ -23,11 +23,12 @@ namespace Boare.Lib.Vsq { | ||||
|     /// </summary> | ||||
|     [Serializable] | ||||
|     public class VsqID : ICloneable { | ||||
|         public const int MAX_NOTE_LENGTH = 16383; | ||||
|         internal int value; | ||||
|         public VsqIDType type; | ||||
|         internal int IconHandle_index; | ||||
|         public IconHandle IconHandle; | ||||
|         public int Length; | ||||
|         private int m_length; | ||||
|         public int Note; | ||||
|         public int Dynamics; | ||||
|         public int PMBendDepth; | ||||
| @ -42,9 +43,28 @@ namespace Boare.Lib.Vsq { | ||||
|         public int VibratoDelay; | ||||
|         internal int NoteHeadHandle_index; | ||||
|         public NoteHeadHandle NoteHeadHandle; | ||||
|         public int pMeanOnsetFirstNote = 0x0a; | ||||
|         public int vMeanNoteTransition = 0x0c; | ||||
|         public int d4mean = 0x18; | ||||
|         public int pMeanEndingNote = 0x0c; | ||||
| 
 | ||||
|         public static VsqID EOS = new VsqID( -1 ); | ||||
| 
 | ||||
|         public int Length { | ||||
|             get { | ||||
|                 return m_length; | ||||
|             } | ||||
|             set { | ||||
|                 if ( value < 0 ) { | ||||
|                     m_length = 0; | ||||
|                 } else if ( MAX_NOTE_LENGTH < value ) { | ||||
|                     m_length = MAX_NOTE_LENGTH; | ||||
|                 } else { | ||||
|                     m_length = value; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// このインスタンスの簡易コピーを取得します。 | ||||
|         /// </summary> | ||||
| @ -63,6 +83,10 @@ namespace Boare.Lib.Vsq { | ||||
|             result.PMbPortamentoUse = this.PMbPortamentoUse; | ||||
|             result.DEMdecGainRate = this.DEMdecGainRate; | ||||
|             result.DEMaccent = this.DEMaccent; | ||||
|             result.d4mean = this.d4mean; | ||||
|             result.pMeanOnsetFirstNote = this.pMeanOnsetFirstNote; | ||||
|             result.vMeanNoteTransition = this.vMeanNoteTransition; | ||||
|             result.pMeanEndingNote = this.pMeanEndingNote; | ||||
|             if ( this.LyricHandle != null ) { | ||||
|                 result.LyricHandle = (LyricHandle)this.LyricHandle.Clone(); | ||||
|             } | ||||
|  | ||||
| @ -845,15 +845,15 @@ namespace Boare.Lib.Vsq { | ||||
|         } | ||||
| 
 | ||||
|         public static bool test( string fpath ) { | ||||
|             VsqMetaText metaText; | ||||
|             /*VsqMetaText metaText; | ||||
|             using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { | ||||
|                 metaText = new VsqMetaText( sr ); | ||||
|             } | ||||
|             }*/ | ||||
|             string result = "test.txt"; | ||||
| 
 | ||||
|             StreamReader honmono = new StreamReader( fpath ); | ||||
|             TextMemoryStream copy = new TextMemoryStream( FileAccess.ReadWrite ); | ||||
|             metaText.print( copy, true, 1000, 100 ); | ||||
|             TextMemoryStream copy = new TextMemoryStream(); | ||||
|             //metaText.print( copy, true, 1000, 100 ); | ||||
|             copy.rewind(); | ||||
|             while ( honmono.Peek() >= 0 && copy.peek() >= 0 ) { | ||||
|                 string hon = honmono.ReadLine(); | ||||
|  | ||||
| @ -22,6 +22,7 @@ namespace Boare.Lib.Vsq { | ||||
|         public byte DataMsb; | ||||
|         public byte DataLsb; | ||||
|         public bool DataLsbSpecified; | ||||
|         public bool msbOmitRequired; | ||||
|         private List<VsqNrpn> m_list; | ||||
| 
 | ||||
|         public VsqNrpn( int clock, ushort nrpn, byte data_msb ) { | ||||
| @ -30,6 +31,7 @@ namespace Boare.Lib.Vsq { | ||||
|             DataMsb = data_msb; | ||||
|             DataLsb = 0x0; | ||||
|             DataLsbSpecified = false; | ||||
|             msbOmitRequired = false; | ||||
|             m_list = new List<VsqNrpn>(); | ||||
|         } | ||||
| 
 | ||||
| @ -39,15 +41,20 @@ namespace Boare.Lib.Vsq { | ||||
|             DataMsb = data_msb; | ||||
|             DataLsb = data_lsb; | ||||
|             DataLsbSpecified = true; | ||||
|             msbOmitRequired = false; | ||||
|             m_list = new List<VsqNrpn>(); | ||||
|         } | ||||
| 
 | ||||
|         public VsqNrpn[] expand() { | ||||
|             List<VsqNrpn> ret = new List<VsqNrpn>(); | ||||
|             if ( DataLsbSpecified ) { | ||||
|                 ret.Add( new VsqNrpn( Clock, Nrpn, DataMsb, DataLsb ) ); | ||||
|                 VsqNrpn v = new VsqNrpn( Clock, Nrpn, DataMsb, DataLsb ); | ||||
|                 v.msbOmitRequired = msbOmitRequired; | ||||
|                 ret.Add( v ); | ||||
|             } else { | ||||
|                 ret.Add( new VsqNrpn( Clock, Nrpn, DataMsb ) ); | ||||
|                 VsqNrpn v = new VsqNrpn( Clock, Nrpn, DataMsb ); | ||||
|                 v.msbOmitRequired = msbOmitRequired; | ||||
|                 ret.Add( v ); | ||||
|             } | ||||
|             for ( int i = 0; i < m_list.Count; i++ ) { | ||||
|                 ret.AddRange( m_list[i].expand() ); | ||||
| @ -123,21 +130,24 @@ namespace Boare.Lib.Vsq { | ||||
|             if ( source[0].DataLsbSpecified ) { | ||||
|                 ret.Add( new NrpnData( source[0].Clock, 0x26, source[0].DataLsb ) ); | ||||
|             } | ||||
|             byte last_msb = msb; | ||||
|             for ( int i = 1; i < source.Length; i++ ) { | ||||
|                 ushort tnrpn = (ushort)source[i].Nrpn; | ||||
|                 VsqNrpn item = source[i]; | ||||
|                 ushort tnrpn = item.Nrpn; | ||||
|                 msb = (byte)(tnrpn >> 8); | ||||
|                 lsb = (byte)(tnrpn - (tnrpn << 8)); | ||||
|                 //if ( msb != last_msb ) { | ||||
|                 ret.Add( new NrpnData( source[i].Clock, 0x63, msb ) ); | ||||
|                 //} else if ( msb == 0x63 ) { | ||||
|                 //    ret.Add( new NrpnData( source[i].Clock, 0x63, msb ) ); | ||||
|                 //} | ||||
|                 last_msb = msb; | ||||
|                 ret.Add( new NrpnData( source[i].Clock, 0x62, lsb ) ); | ||||
|                 ret.Add( new NrpnData( source[i].Clock, 0x06, source[i].DataMsb ) ); | ||||
|                 if ( source[i].DataLsbSpecified ) { | ||||
|                     ret.Add( new NrpnData( source[i].Clock, 0x26, source[i].DataLsb ) ); | ||||
|                 if ( item.msbOmitRequired ) { | ||||
|                     ret.Add( new NrpnData( item.Clock, 0x62, lsb ) ); | ||||
|                     ret.Add( new NrpnData( item.Clock, 0x06, item.DataMsb ) ); | ||||
|                     if ( item.DataLsbSpecified ) { | ||||
|                         ret.Add( new NrpnData( item.Clock, 0x26, item.DataLsb ) ); | ||||
|                     } | ||||
|                 } else { | ||||
|                     ret.Add( new NrpnData( item.Clock, 0x63, msb ) ); | ||||
|                     ret.Add( new NrpnData( item.Clock, 0x62, lsb ) ); | ||||
|                     ret.Add( new NrpnData( item.Clock, 0x06, item.DataMsb ) ); | ||||
|                     if ( item.DataLsbSpecified ) { | ||||
|                         ret.Add( new NrpnData( item.Clock, 0x26, item.DataLsb ) ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return ret.ToArray(); | ||||
| @ -154,6 +164,18 @@ namespace Boare.Lib.Vsq { | ||||
|         public void append( ushort nrpn, byte data_msb, byte data_lsb ) { | ||||
|             m_list.Add( new VsqNrpn( Clock, nrpn, data_msb, data_lsb ) ); | ||||
|         } | ||||
| 
 | ||||
|         public void append( ushort nrpn, byte data_msb, bool msb_omit_required ) { | ||||
|             VsqNrpn v = new VsqNrpn( Clock, nrpn, data_msb ); | ||||
|             v.msbOmitRequired = msb_omit_required; | ||||
|             m_list.Add( v ); | ||||
|         } | ||||
| 
 | ||||
|         public void append( ushort nrpn, byte data_msb, byte data_lsb, bool msb_omit_required ) { | ||||
|             VsqNrpn v = new VsqNrpn( Clock, nrpn, data_msb, data_lsb ); | ||||
|             v.msbOmitRequired = msb_omit_required; | ||||
|             m_list.Add( v ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -131,6 +131,18 @@ namespace Boare.Lib.Vsq { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// ピッチベンド。Cent単位 | ||||
|         /// </summary> | ||||
|         /// <param name="clock"></param> | ||||
|         /// <returns></returns> | ||||
|         public double getPitchAt( int clock ) { | ||||
|             double inv2_13 = 1.0 / 8192.0; | ||||
|             int pit = MetaText.PIT.getValue( clock ); | ||||
|             int pbs = MetaText.PBS.getValue( clock ); | ||||
|             return (double)pit * (double)pbs * inv2_13 * 100.0; | ||||
|         } | ||||
| 
 | ||||
|         public void sortEvent() { | ||||
|             MetaText.Events.sort(); | ||||
|         } | ||||
| @ -171,7 +183,7 @@ namespace Boare.Lib.Vsq { | ||||
|         /// </summary> | ||||
|         /// <param name="file"></param> | ||||
|         public void printMetaText( string file ) { | ||||
|             TextMemoryStream tms = new TextMemoryStream( FileAccess.ReadWrite ); | ||||
|             TextMemoryStream tms = new TextMemoryStream(); | ||||
|             int count = MetaText.getEventList().getCount(); | ||||
|             int clLast = MetaText.getEventList().getElement( count - 1 ).Clock + 480; | ||||
|             MetaText.print( tms, true, clLast, 0 ); | ||||
| @ -278,6 +290,10 @@ namespace Boare.Lib.Vsq { | ||||
|             return MetaText.getEventList().getElement( index ); | ||||
|         } | ||||
| 
 | ||||
|         public VsqEvent findEventFromID( int internal_id ) { | ||||
|             return MetaText.getEventList().findFromID( internal_id ); | ||||
|         } | ||||
| 
 | ||||
|         public void setEvent( int index, VsqEvent item ) { | ||||
|             MetaText.getEventList().setElement( index, item ); | ||||
|         } | ||||
| @ -390,21 +406,30 @@ namespace Boare.Lib.Vsq { | ||||
| #endif | ||||
|             using ( TextMemoryStream sw = new TextMemoryStream() ) { | ||||
|                 for ( int i = 0; i < midi_event.Count; i++ ) { | ||||
|                     if ( midi_event[i].FirstByte == 0xff && midi_event[i].Data.Length > 0 ) { | ||||
|                     if ( midi_event[i].firstByte == 0xff && midi_event[i].data.Length > 0 ) { | ||||
|                         // meta textを抽出 | ||||
|                         byte type = midi_event[i].Data[0]; | ||||
|                         byte type = midi_event[i].data[0]; | ||||
|                         if ( type == 0x01 || type == 0x03 ) { | ||||
|                             char[] ch = new char[midi_event[i].Data.Length - 1]; | ||||
|                             for ( int j = 1; j < midi_event[i].Data.Length; j++ ) { | ||||
|                                 ch[j - 1] = (char)midi_event[i].Data[j]; | ||||
|                             char[] ch = new char[midi_event[i].data.Length - 1]; | ||||
|                             for ( int j = 1; j < midi_event[i].data.Length; j++ ) { | ||||
|                                 ch[j - 1] = (char)midi_event[i].data[j]; | ||||
|                             } | ||||
|                             string line = new string( ch ); | ||||
|                             if ( type == 0x01 ) { | ||||
|                                 int second_colon = line.IndexOf( ':', 3 ); | ||||
|                                 line = line.Substring( second_colon + 1 ); | ||||
|                                 line = line.Replace( "\\n", Environment.NewLine ); | ||||
|                                 line = line.Replace( "\n", Environment.NewLine ); | ||||
|                                 sw.write( line ); | ||||
|                                 line = line.Replace( "\\n", "\n" ); | ||||
|                                 //line = line.Replace( "\n", Environment.NewLine ); | ||||
|                                 string[] lines = line.Split( '\n' ); | ||||
|                                 int c = lines.Length; | ||||
|                                 for ( int j = 0; j < c; j++ ) { | ||||
|                                     if ( j < c - 1 ) { | ||||
|                                         sw.writeLine( lines[j] ); | ||||
|                                     } else { | ||||
|                                         sw.write( lines[j] ); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 //sw.write( line ); | ||||
|                             } else { | ||||
|                                 Name = line; | ||||
|                             } | ||||
|  | ||||
							
								
								
									
										34
									
								
								trunk/Boare.Lib.Vsq/VsqVoiceLanguage.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								trunk/Boare.Lib.Vsq/VsqVoiceLanguage.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * VsqVoiceLanguage.cs | ||||
|  * Copyright (c) 2008-2009 kbinani | ||||
|  * | ||||
|  * This file is part of Boare.Lib.Vsq. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the BSD License. | ||||
|  * | ||||
|  * Boare.Lib.Vsq is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| namespace Boare.Lib.Vsq { | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Represents the voice language of singer. | ||||
|     /// </summary> | ||||
|     public enum VsqVoiceLanguage : int { | ||||
|         /// <summary> | ||||
|         /// Default value, equivalent to "Japanese". | ||||
|         /// </summary> | ||||
|         Default = 0, | ||||
|         /// <summary> | ||||
|         /// Japanese | ||||
|         /// </summary> | ||||
|         Japanese = 0, | ||||
|         /// <summary> | ||||
|         /// English | ||||
|         /// </summary> | ||||
|         English = 1, | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user