/* * 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 dir1 = new Vector(); 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 installed_singers1 = new Vector(); 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 dir2 = new Vector(); 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 installed_singers2 = new Vector(); 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 dir, String header, out String path_vsti, out String path_voicedb, out String path_expdb, out String path_editor, Vector installed_singers ) { Vector application = new Vector(); Vector expression = new Vector(); Vector voice = new Vector(); 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 voice_ids = new Vector(); // 最初は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 exp_ids = new Vector(); // 最初は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 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 ); } } } /// /// Gets the name of original singer of specified program change. /// /// /// 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 ""; } /// /// Gets the name of original singer of specified program change. /// /// /// 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(); } /// /// Gets the voice language of specified program change /// /// name of singer /// 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 ); } /// /// Transform the byte array(length=8) to unsigned long, assuming that the byte array is little endian. /// /// /// 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 s_installed_singers2 = new List(); private static List s_singer_configs2 = new List(); private static string s_dll_path1 = ""; private static string s_editor_path1 = ""; private static string s_voicedbdir1 = ""; private static List s_installed_singers1 = new List(); private static List s_singer_configs1 = new List(); private const int MAX_SINGERS = 0x4000; static VocaloSysUtil_() { init_vocalo2(); init_vocalo1(); } /// /// Gets the name of original singer of specified program change. /// /// /// 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 ""; } /// /// Gets the name of original singer of specified program change. /// /// /// 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 ""; } /// /// Gets the voice language of specified program change /// /// name of singer /// 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; } /// /// VOCALOID1システムのプロパティを取得 /// 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 vvoice_keys = new List(); List vvoice_values = new List(); 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 } /// /// VOCALOID2システムのプロパティを取得 /// 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 vvoice_keys = new List(); List vvoice_values = new List(); 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 } /// /// Transform the byte array(length=8) to unsigned long, assuming that the byte array is little endian. /// /// /// 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]; } } }