mirror of
https://git.femboyfinancial.jp/james/lipsync.git
synced 2024-11-21 10:12:04 -08:00
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…
Reference in New Issue
Block a user