2009-06-25 07:16:22 -07:00
|
|
|
|
/*
|
|
|
|
|
* SingerConfig.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.
|
|
|
|
|
*/
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
namespace Boare.Lib.Vsq {
|
|
|
|
|
|
2009-07-29 10:03:20 -07:00
|
|
|
|
public class SingerConfig : ICloneable {
|
|
|
|
|
public string ID = "";
|
|
|
|
|
public string FORMAT = "";
|
|
|
|
|
public string VOICEIDSTR = "";
|
|
|
|
|
public string VOICENAME = "Unknown";
|
2009-06-25 07:16:22 -07:00
|
|
|
|
public int Breathiness;
|
|
|
|
|
public int Brightness;
|
|
|
|
|
public int Clearness;
|
|
|
|
|
public int Opening;
|
|
|
|
|
public int GenderFactor;
|
|
|
|
|
public int Original;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
public int Program;
|
|
|
|
|
|
|
|
|
|
public SingerConfig() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public object Clone() {
|
|
|
|
|
SingerConfig ret = new SingerConfig();
|
|
|
|
|
ret.ID = ID;
|
|
|
|
|
ret.FORMAT = FORMAT;
|
|
|
|
|
ret.VOICEIDSTR = VOICEIDSTR;
|
|
|
|
|
ret.VOICENAME = VOICENAME;
|
|
|
|
|
ret.Breathiness = Breathiness;
|
|
|
|
|
ret.Brightness = Brightness;
|
|
|
|
|
ret.Clearness = Clearness;
|
|
|
|
|
ret.Opening = Opening;
|
|
|
|
|
ret.GenderFactor = GenderFactor;
|
|
|
|
|
ret.Original = Original;
|
|
|
|
|
ret.Program = Program;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-29 10:03:20 -07:00
|
|
|
|
public static SingerConfig readSingerConfig( string file, int original ) {
|
|
|
|
|
SingerConfig sc = new SingerConfig();
|
|
|
|
|
//original = original;
|
|
|
|
|
sc.ID = "VOCALOID:VIRTUAL:VOICE";
|
|
|
|
|
sc.FORMAT = "2.0.0.0";
|
|
|
|
|
sc.VOICEIDSTR = "";
|
|
|
|
|
sc.VOICENAME = "Miku";
|
|
|
|
|
sc.Breathiness = 0;
|
|
|
|
|
sc.Brightness = 0;
|
|
|
|
|
sc.Clearness = 0;
|
|
|
|
|
sc.Opening = 0;
|
|
|
|
|
sc.GenderFactor = 0;
|
|
|
|
|
sc.Original = original; //original = 0;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
FileStream fs = null;
|
|
|
|
|
try {
|
|
|
|
|
fs = new FileStream( file, FileMode.Open, FileAccess.Read );
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
string str = bocoree.cp932.convert( dat );
|
|
|
|
|
string crlf = ((char)0x0d).ToString() + ((char)0x0a).ToString();
|
|
|
|
|
string[] spl = str.Split( new string[] { crlf }, StringSplitOptions.RemoveEmptyEntries );
|
|
|
|
|
|
|
|
|
|
foreach ( string s in spl ) {
|
|
|
|
|
int first = s.IndexOf( '"' );
|
|
|
|
|
int first_end = get_quated_string( s, first );
|
|
|
|
|
int second = s.IndexOf( '"', first_end + 1 );
|
|
|
|
|
int second_end = get_quated_string( s, second );
|
|
|
|
|
char[] chs = s.ToCharArray();
|
|
|
|
|
string id = new string( chs, first, first_end - first + 1 );
|
|
|
|
|
string value = new string( chs, second, second_end - second + 1 );
|
|
|
|
|
id = id.Substring( 1, id.Length - 2 );
|
|
|
|
|
value = value.Substring( 1, value.Length - 2 );
|
|
|
|
|
value = value.Replace( "\\\"", "\"" );
|
|
|
|
|
if ( id == "ID" ) {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.ID = value;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} else if ( id == "FORMAT" ) {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.FORMAT = value;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} else if ( id == "VOICEIDSTR" ) {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.VOICEIDSTR = value;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} else if ( id == "VOICENAME" ) {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.VOICENAME = value;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} else if ( id == "Breathiness" ) {
|
|
|
|
|
try {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.Breathiness = int.Parse( value );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} catch {
|
|
|
|
|
}
|
|
|
|
|
} else if ( id == "Brightness" ) {
|
|
|
|
|
try {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.Brightness = int.Parse( value );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} catch {
|
|
|
|
|
}
|
|
|
|
|
} else if ( id == "Clearness" ) {
|
|
|
|
|
try {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.Clearness = int.Parse( value );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} catch {
|
|
|
|
|
}
|
|
|
|
|
} else if ( id == "Opening" ) {
|
|
|
|
|
try {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.Opening = int.Parse( value );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} catch {
|
|
|
|
|
}
|
|
|
|
|
} else if ( id == "Gender:Factor" ) {
|
|
|
|
|
try {
|
2009-07-29 10:03:20 -07:00
|
|
|
|
sc.GenderFactor = int.Parse( value );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
} catch {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
if ( fs != null ) {
|
|
|
|
|
fs.Close();
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-29 10:03:20 -07:00
|
|
|
|
return sc;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 位置positionにある'"'から,次に現れる'"'の位置を調べる.エスケープされた\"はスキップされる.'"'が見つからなかった場合-1を返す
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="s"></param>
|
|
|
|
|
/// <param name="position"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
static int get_quated_string( string s, int position ) {
|
|
|
|
|
if ( position < 0 ) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
char[] chs = s.ToCharArray();
|
|
|
|
|
if ( position >= chs.Length ) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if ( chs[position] != '"' ) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int end = -1;
|
|
|
|
|
for ( int i = position + 1; i < chs.Length; i++ ) {
|
|
|
|
|
if ( chs[i] == '"' && chs[i - 1] != '\\' ) {
|
|
|
|
|
end = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return end;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-29 10:03:20 -07:00
|
|
|
|
public string[] ToStringArray() {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
List<string> ret = new List<string>();
|
|
|
|
|
ret.Add( "\"ID\":=:\"" + ID + "\"" );
|
|
|
|
|
ret.Add( "\"FORMAT\":=:\"" + FORMAT + "\"" );
|
|
|
|
|
ret.Add( "\"VOICEIDSTR\":=:\"" + VOICEIDSTR + "\"" );
|
|
|
|
|
ret.Add( "\"VOICENAME\":=:\"" + VOICENAME.Replace( "\"", "\\\"" ) + "\"" );
|
|
|
|
|
ret.Add( "\"Breathiness\":=:\"" + Breathiness + "\"" );
|
|
|
|
|
ret.Add( "\"Brightness\":=:\"" + Brightness + "\"" );
|
|
|
|
|
ret.Add( "\"Clearness\":=:\"" + Clearness + "\"" );
|
|
|
|
|
ret.Add( "\"Opening\":=:\"" + Opening + "\"" );
|
|
|
|
|
ret.Add( "\"Gender:Factor\":=:\"" + GenderFactor + "\"" );
|
|
|
|
|
return ret.ToArray();
|
|
|
|
|
}
|
2009-07-29 10:03:20 -07:00
|
|
|
|
|
|
|
|
|
public override string ToString() {
|
|
|
|
|
string[] r = ToStringArray();
|
|
|
|
|
string ret = "";
|
|
|
|
|
foreach ( string s in r ) {
|
|
|
|
|
ret += s + "\n";
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|