lipsync/Boare.Lib.Vsq/VocaloSysUtil.cs
2024-05-20 00:17:44 +00:00

454 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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.
*/
#if JAVA
package org.kbinani.vsq;
import java.io.*;
import java.util.*;
import org.kbinani.*;
#else
using System;
using System.Collections.Generic;
using Microsoft.Win32;
using bocoree;
using bocoree.java.util;
using bocoree.java.io;
namespace Boare.Lib.Vsq {
#endif
public class VocaloSysUtil {
private static TreeMap<SynthesizerType, SingerConfigSys> s_singer_config_sys = new TreeMap<SynthesizerType, SingerConfigSys>();
private static TreeMap<SynthesizerType, ExpressionConfigSys> s_exp_config_sys = new TreeMap<SynthesizerType, ExpressionConfigSys>();
private static TreeMap<SynthesizerType, String> s_path_vsti = new TreeMap<SynthesizerType, String>();
private static TreeMap<SynthesizerType, String> s_path_editor = new TreeMap<SynthesizerType, String>();
private VocaloSysUtil() {
}
#if JAVA
static{
#else
static VocaloSysUtil() {
#endif
ExpressionConfigSys exp_config_sys1 = null;
try {
Vector<String> dir1 = new Vector<String>();
ByRef<String> path_voicedb1 = new ByRef<String>( "" );
ByRef<String> path_expdb1 = new ByRef<String>( "" );
Vector<String> installed_singers1 = new Vector<String>();
String header1 = "HKLM\\SOFTWARE\\VOCALOID";
print( "SOFTWARE\\VOCALOID", header1, dir1 );
#if DEBUG
BufferedWriter sw = null;
try {
sw = new BufferedWriter( new FileWriter( PortUtil.combinePath( System.Windows.Forms.Application.StartupPath, "reg_keys_vocalo1.txt" ) ) );
foreach ( String s in dir1 ) {
sw.write( s );
sw.newLine();
}
} catch ( Exception ex ) {
} finally {
if ( sw != null ) {
try {
sw.close();
} catch ( Exception ex2 ) {
}
}
}
#endif
ByRef<String> path_vsti = new ByRef<String>( "" );
ByRef<String> path_editor = new ByRef<String>( "" );
extract( dir1,
header1,
path_vsti,
path_voicedb1,
path_expdb1,
path_editor,
installed_singers1 );
s_path_vsti.put( SynthesizerType.VOCALOID1, path_vsti.value );
s_path_editor.put( SynthesizerType.VOCALOID1, path_editor.value );
SingerConfigSys singer_config_sys = new SingerConfigSys( path_voicedb1.value, installed_singers1.toArray( new String[] { } ) );
if ( PortUtil.isFileExists( PortUtil.combinePath( path_expdb1.value, "expression.map" ) ) ) {
exp_config_sys1 = new ExpressionConfigSys( path_expdb1.value );
}
s_singer_config_sys.put( SynthesizerType.VOCALOID1, singer_config_sys );
} catch ( Exception ex ) {
PortUtil.println( "VocaloSysUtil..cctor; ex=" + ex );
SingerConfigSys singer_config_sys = new SingerConfigSys( "", new String[] { } );
exp_config_sys1 = null;
s_singer_config_sys.put( SynthesizerType.VOCALOID1, singer_config_sys );
}
if ( exp_config_sys1 == null ) {
exp_config_sys1 = ExpressionConfigSys.getVocaloid1Default();
}
s_exp_config_sys.put( SynthesizerType.VOCALOID1, exp_config_sys1 );
ExpressionConfigSys exp_config_sys2 = null;
try {
Vector<String> dir2 = new Vector<String>();
ByRef<String> path_voicedb2 = new ByRef<String>( "" );
ByRef<String> path_expdb2 = new ByRef<String>( "" );
Vector<String> installed_singers2 = new Vector<String>();
String header2 = "HKLM\\SOFTWARE\\VOCALOID2";
print( "SOFTWARE\\VOCALOID2", header2, dir2 );
#if DEBUG
BufferedWriter sw = null;
try {
sw = new BufferedWriter( new FileWriter( PortUtil.combinePath( System.Windows.Forms.Application.StartupPath, "reg_keys_vocalo2.txt" ) ) );
foreach ( String s in dir2 ) {
sw.write( s );
sw.newLine();
}
} catch ( Exception ex ) {
} finally {
if ( sw != null ) {
try {
sw.close();
} catch ( Exception ex2 ) {
}
}
}
#endif
ByRef<String> path_vsti = new ByRef<String>( "" );
ByRef<String> path_editor = new ByRef<String>( "" );
extract( dir2,
header2,
path_vsti,
path_voicedb2,
path_expdb2,
path_editor,
installed_singers2 );
s_path_vsti.put( SynthesizerType.VOCALOID2, path_vsti.value );
s_path_editor.put( SynthesizerType.VOCALOID2, path_editor.value );
SingerConfigSys singer_config_sys = new SingerConfigSys( path_voicedb2.value, installed_singers2.toArray( new String[] { } ) );
if ( PortUtil.isFileExists( PortUtil.combinePath( path_expdb2.value, "expression.map" ) ) ) {
exp_config_sys2 = new ExpressionConfigSys( path_expdb2.value );
}
s_singer_config_sys.put( SynthesizerType.VOCALOID2, singer_config_sys );
} catch ( Exception ex ) {
PortUtil.println( "VocaloSysUtil..cctor; ex=" + ex );
SingerConfigSys singer_config_sys = new SingerConfigSys( "", new String[] { } );
exp_config_sys2 = null;
s_singer_config_sys.put( SynthesizerType.VOCALOID2, singer_config_sys );
}
if ( exp_config_sys2 == null ) {
exp_config_sys2 = ExpressionConfigSys.getVocaloid2Default();
}
s_exp_config_sys.put( SynthesizerType.VOCALOID2, exp_config_sys2 );
#if DEBUG
SingerConfigSys scs2 = s_singer_config_sys.get( SynthesizerType.VOCALOID2 );
foreach( SingerConfig sc in scs2.getInstalledSingers() ){
PortUtil.println( "VocaloSysUtil#.ctor; sc=" + sc.toString() );
}
#endif
}
/// <summary>
/// ビブラートのプリセットタイプからVibratoHandleを作成します
/// </summary>
/// <param name="type"></param>
/// <param name="vibrato_clocks"></param>
/// <returns></returns>
public static VibratoHandle getDefaultVibratoHandle( String icon_id, int vibrato_length, SynthesizerType type ) {
if ( s_exp_config_sys.containsKey( type ) ) {
for ( Iterator itr = s_exp_config_sys.get( type ).vibratoConfigIterator(); itr.hasNext(); ) {
VibratoConfig vconfig = (VibratoConfig)itr.next();
if ( vconfig.contents.IconID.Equals( icon_id ) ) {
VibratoHandle ret = (VibratoHandle)vconfig.contents.clone();
ret.setLength( vibrato_length );
return ret;
}
}
}
VibratoHandle empty = new VibratoHandle();
empty.IconID = "$04040000";
return empty;
}
private static void extract( Vector<String> dir,
String header,
ByRef<String> path_vsti,
ByRef<String> path_voicedb,
ByRef<String> path_expdb,
ByRef<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.value = "";
path_expdb.value = "";
path_voicedb.value = "";
path_editor.value = "";
for ( Iterator itr = dir.iterator(); itr.hasNext(); ) {
String s = (String)itr.next();
if ( s.StartsWith( header + "\\APPLICATION" ) ) {
application.add( s.Substring( PortUtil.getStringLength( header + "\\APPLICATION" ) ) );
} else if ( s.StartsWith( header + "\\DATABASE\\EXPRESSION" ) ) {
expression.add( s.Substring( PortUtil.getStringLength( header + "\\DATABASE\\EXPRESSION" ) ) );
} else if ( s.StartsWith( header + "\\DATABASE\\VOICE" ) ) {
voice.add( s.Substring( PortUtil.getStringLength( header + "\\DATABASE\\VOICE\\" ) ) );
}
}
// path_vstiを取得
for ( Iterator itr = application.iterator(); itr.hasNext(); ) {
String s = (String)itr.next();
String[] spl = PortUtil.splitString( s, '\t' );
if ( spl.Length >= 3 && spl[1].Equals( "PATH" ) ) {
if ( spl[2].ToLower().EndsWith( ".dll" ) ) {
path_vsti.value = spl[2];
} else if ( spl[2].ToLower().EndsWith( ".exe" ) ) {
path_editor.value = spl[2];
}
}
}
// path_vicedbを取得
TreeMap<String, String> install_dirs = new TreeMap<String, String>();
// 最初はpath_voicedbの取得と、idBHXXXXXXXXXXXXXXXXのようなシリアルを取得
for ( Iterator itr = voice.iterator(); itr.hasNext(); ) {
String s = (String)itr.next();
String[] spl = PortUtil.splitString( s, '\t' );
if ( spl.Length >= 2 ) {
if ( spl[0].Equals( "VOICEDIR" ) ) {
path_voicedb.value = spl[1];
} else if ( spl.Length >= 3 ) {
String[] spl2 = PortUtil.splitString( spl[0], '\\' );
if ( spl2.Length == 1 ){
if ( !install_dirs.containsKey( spl2[0] ) ) {
String install = "";
if ( spl[1].Equals( "INSTALLDIR" ) ) {
install = spl[2];
}
install_dirs.put( spl2[0], install );
} else {
if ( spl[1].Equals( "INSTALLDIR" ) ) {
install_dirs.put( spl2[0], spl[2] );
}
}
}
}
}
}
// installed_singersに追加
for ( Iterator itr = install_dirs.keySet().iterator(); itr.hasNext(); ) {
String id = (String)itr.next();
String install = install_dirs.get( id );
if ( id.Equals( "" ) ) {
install = path_voicedb.value;
}
installed_singers.add( install );
}
// path_expdbを取得
Vector<String> exp_ids = new Vector<String>();
// 最初はpath_expdbの取得と、idBHXXXXXXXXXXXXXXXXのようなシリアルを取得
for ( Iterator itr = expression.iterator(); itr.hasNext(); ) {
String s = (String)itr.next();
#if DEBUG
PortUtil.println( "VocaloSysUtil#extract; s=" + s );
#endif
String[] spl = PortUtil.splitString( s, new char[] { '\t' }, true );
if ( spl.Length >= 2 ) {
if ( spl[0].Equals( "EXPRESSIONDIR" ) ) {
path_expdb.value = spl[1];
} else if ( spl.Length >= 3 ) {
String[] spl2 = PortUtil.splitString( spl[0], '\\' );
if ( spl2.Length == 1 ) {
if ( !exp_ids.contains( spl2[0] ) ) {
exp_ids.add( spl2[0] );
}
}
}
}
}
#if DEBUG
PortUtil.println( "path_vsti=" + path_vsti.value );
PortUtil.println( "path_voicedb=" + path_voicedb.value );
PortUtil.println( "path_expdb=" + path_expdb.value );
PortUtil.println( "installed_singers=" );
for ( Iterator itr = installed_singers.iterator(); itr.hasNext(); ) {
String s = (String)itr.next();
PortUtil.println( " " + s );
}
#endif
}
/// <summary>
/// レジストリkey内の値を再帰的に検索し、ファイルfpに順次出力する
/// </summary>
/// <param name="key"></param>
/// <param name="parent_name"></param>
/// <param name="list"></param>
private static void print( String reg_key_name, String parent_name, Vector<String> list ) {
#if JAVA
#else
RegistryKey key = Registry.LocalMachine.OpenSubKey( reg_key_name, false );
if ( key == null ) {
return;
}
// 直下のキー内を再帰的にリストアップ
String[] subkeys = key.GetSubKeyNames();
foreach ( String s in subkeys ) {
print( reg_key_name + "\\" + s, parent_name + "\\" + s, list );
}
// 直下の値を出力
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 );
}
}
key.Close();
#endif
}
public static Iterator attackConfigIterator( SynthesizerType type ) {
if ( s_exp_config_sys.containsKey( type ) ) {
return s_exp_config_sys.get( type ).attackConfigIterator();
} else {
return (new Vector<AttackConfig>()).iterator();
}
}
public static Iterator vibratoConfigIterator( SynthesizerType type ) {
if ( s_exp_config_sys.containsKey( type ) ) {
return s_exp_config_sys.get( type ).vibratoConfigIterator();
} else {
return (new Vector<AttackConfig>()).iterator();
}
}
/// <summary>
/// Gets the name of original singer of specified program change.
/// </summary>
/// <param name="singer"></param>
/// <returns></returns>
public static String getOriginalSinger( String singer, SynthesizerType type ) {
String voiceidstr = "";
if ( !s_singer_config_sys.containsKey( type ) ) {
return "";
}
SingerConfigSys scs = s_singer_config_sys.get( type );
SingerConfig[] singer_configs = scs.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 = scs.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 getSingerID( String singer, SynthesizerType type ) {
if ( !s_singer_config_sys.containsKey( type ) ) {
return null;
} else {
return s_singer_config_sys.get( type ).getSingerID( singer );
}
}
public static String getEditorPath( SynthesizerType type ) {
if ( !s_path_editor.containsKey( type ) ) {
return "";
} else {
return s_path_editor.get( type );
}
}
public static String getDllPathVsti( SynthesizerType type ) {
if ( !s_path_vsti.containsKey( type ) ) {
return "";
} else {
return s_path_vsti.get( type );
}
}
public static SingerConfig[] getSingerConfigs( SynthesizerType type ) {
if ( !s_singer_config_sys.containsKey( type ) ) {
return new SingerConfig[] { };
} else {
return s_singer_config_sys.get( type ).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 ) {
String search = name.ToLower();
if ( search.Equals( "meiko" ) ||
search.Equals( "kaito" ) ||
search.Equals( "miku" ) ||
search.Equals( "rin" ) ||
search.Equals( "len" ) ||
search.Equals( "rin_act2" ) ||
search.Equals( "len_act2" ) ||
search.Equals( "gackpoid" ) ||
search.Equals( "luka_jpn" ) ||
search.Equals( "megpoid" ) ) {
return VsqVoiceLanguage.Japanese;
} else if ( search.Equals( "sweet_ann" ) ||
search.Equals( "prima" ) ||
search.Equals( "luka_eng" ) ||
search.Equals( "sonika" ) ) {
return VsqVoiceLanguage.English;
}
return VsqVoiceLanguage.Japanese;
}
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 long makelong_le( byte[] oct ) {
return (long)oct[7] << 56 | (long)oct[6] << 48 | (long)oct[5] << 40 | (long)oct[4] << 32 | (long)oct[3] << 24 | (long)oct[2] << 16 | (long)oct[1] << 8 | (long)oct[0];
}
}
#if !JAVA
}
#endif