2010-03-16 20:14:08 -07:00
|
|
|
|
/*
|
2009-06-25 07:16:22 -07:00
|
|
|
|
* UstFile.cs
|
|
|
|
|
* Copyright (c) 2009 kbinani, PEX
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if JAVA
|
|
|
|
|
package org.kbinani.vsq;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import org.kbinani.*;
|
|
|
|
|
#else
|
|
|
|
|
using System;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
using bocoree;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
using bocoree.java.util;
|
|
|
|
|
using bocoree.java.io;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
namespace Boare.Lib.Vsq {
|
|
|
|
|
using Float = System.Single;
|
|
|
|
|
using boolean = System.Boolean;
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if JAVA
|
|
|
|
|
public class UstFile implements Cloneable {
|
|
|
|
|
#else
|
2009-06-25 07:16:22 -07:00
|
|
|
|
public class UstFile : ICloneable {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// [#PREV]が指定されているUstEventのIndex
|
|
|
|
|
/// </summary>
|
|
|
|
|
public const int PREV_INDEX = int.MinValue;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// [#NEXT]が指定されているUstEventのIndex
|
|
|
|
|
/// </summary>
|
|
|
|
|
public const int NEXT_INDEX = int.MaxValue;
|
|
|
|
|
|
|
|
|
|
public Object Tag;
|
2009-07-29 10:03:20 -07:00
|
|
|
|
private float m_tempo = 120.00f;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
private String m_project_name = "";
|
|
|
|
|
private String m_voice_dir = "";
|
|
|
|
|
private String m_out_file = "";
|
|
|
|
|
private String m_cache_dir = "";
|
|
|
|
|
private String m_tool1 = "";
|
|
|
|
|
private String m_tool2 = "";
|
|
|
|
|
private Vector<UstTrack> m_tracks = new Vector<UstTrack>();
|
|
|
|
|
private Vector<TempoTableEntry> m_tempo_table;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
|
|
|
|
|
public UstFile( String path ) {
|
|
|
|
|
BufferedReader sr = null;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
try {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
sr = new BufferedReader( new InputStreamReader( new FileInputStream( path ), "Shift_JIS" ) );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
#if DEBUG
|
|
|
|
|
bocoree.debug.push_log( "path=" + path );
|
|
|
|
|
bocoree.debug.push_log( "(sr==null)=" + (sr == null) );
|
|
|
|
|
#endif
|
2010-03-16 20:14:08 -07:00
|
|
|
|
String line = sr.readLine();
|
|
|
|
|
if ( !line.Equals( "[#SETTING]" ) ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
throw new Exception( "invalid ust file" );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
UstTrack track = new UstTrack();
|
|
|
|
|
int type = 0; //0 => reading "SETTING" section
|
|
|
|
|
while ( true ) {
|
|
|
|
|
#if DEBUG
|
2010-03-16 20:14:08 -07:00
|
|
|
|
PortUtil.println( "line=" + line );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
#endif
|
|
|
|
|
UstEvent ue = null;
|
|
|
|
|
if ( type == 1 ) {
|
|
|
|
|
ue = new UstEvent();
|
|
|
|
|
}
|
|
|
|
|
int index = 0;
|
|
|
|
|
if ( line.Equals( "[#TRACKEND]" ) ) {
|
|
|
|
|
break;
|
|
|
|
|
} else if ( line.ToUpper().Equals( "[#NEXT]" ) ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
index = NEXT_INDEX;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
} else if ( line.ToUpper().Equals( "[#PREV]" ) ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
index = PREV_INDEX;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
} else {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
String s = line.Replace( "[#", "" ).Replace( "]", "" ).Trim();
|
|
|
|
|
try {
|
|
|
|
|
index = PortUtil.parseInt( s );
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
#if DEBUG
|
|
|
|
|
PortUtil.println( "UstFile#.ctor; ex=" + ex );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
#if DEBUG
|
|
|
|
|
bocoree.debug.push_log( "index=" + index );
|
|
|
|
|
#endif
|
2010-03-16 20:14:08 -07:00
|
|
|
|
line = sr.readLine(); // "[#" 直下の行
|
2009-09-07 03:44:18 -07:00
|
|
|
|
if ( line == null ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
while ( !line.StartsWith( "[#" ) ) {
|
|
|
|
|
#if DEBUG
|
2010-03-16 20:14:08 -07:00
|
|
|
|
PortUtil.println( "line=" + line );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
#endif
|
2010-03-16 20:14:08 -07:00
|
|
|
|
String[] spl = PortUtil.splitString( line, new char[] { '=' }, 2 );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
if ( type == 0 ) {
|
|
|
|
|
// reading "SETTING" section
|
|
|
|
|
if ( spl[0].Equals( "Tempo" ) ) {
|
|
|
|
|
m_tempo = 125f;
|
|
|
|
|
float v = 125f;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseFloat( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
m_tempo = v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "ProjectName" ) ) {
|
|
|
|
|
m_project_name = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "VoiceDir" ) ) {
|
|
|
|
|
m_voice_dir = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "OutFile" ) ) {
|
|
|
|
|
m_out_file = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "CacheDir" ) ) {
|
|
|
|
|
m_cache_dir = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "Tool1" ) ) {
|
|
|
|
|
m_tool1 = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "Tool2" ) ) {
|
|
|
|
|
m_tool2 = spl[1];
|
2009-07-29 10:03:20 -07:00
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
} else if ( type == 1 ) {
|
|
|
|
|
// readin event section
|
|
|
|
|
if ( spl[0].Equals( "Length" ) ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
ue.setLength( 0 );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
int v = 0;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseInt( spl[1] );
|
|
|
|
|
ue.setLength( v );
|
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "Lyric" ) ) {
|
|
|
|
|
ue.Lyric = spl[1];
|
|
|
|
|
} else if ( spl[0].Equals( "NoteNum" ) ) {
|
|
|
|
|
ue.Note = 0;
|
|
|
|
|
int v = 0;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseInt( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
ue.Note = v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "Intensity" ) ) {
|
|
|
|
|
ue.Intensity = 64;
|
|
|
|
|
int v = 64;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseInt( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
ue.Intensity = v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "PBType" ) ) {
|
|
|
|
|
ue.PBType = 5;
|
|
|
|
|
int v = 5;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseInt( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
ue.PBType = v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "Piches" ) ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
String[] spl2 = PortUtil.splitString( spl[1], ',' );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
float[] t = new float[spl2.Length];
|
|
|
|
|
for ( int i = 0; i < spl2.Length; i++ ) {
|
|
|
|
|
float v = 0;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseFloat( spl2[i] );
|
|
|
|
|
t[i] = v;
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
ue.Pitches = t;
|
|
|
|
|
} else if ( spl[0].Equals( "Tempo" ) ) {
|
|
|
|
|
ue.Tempo = 125f;
|
|
|
|
|
float v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
try {
|
|
|
|
|
v = PortUtil.parseFloat( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
ue.Tempo = v;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} catch ( Exception ex ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "VBR" ) ) {
|
|
|
|
|
ue.Vibrato = new UstVibrato( line );
|
|
|
|
|
/*
|
|
|
|
|
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
|
|
|
|
|
*/
|
|
|
|
|
} else if ( spl[0].Equals( "PBW" ) || spl[0].Equals( "PBS" ) || spl[0].Equals( "PBY" ) || spl[0].Equals( "PBM" ) ) {
|
|
|
|
|
if ( ue.Portamento == null ) {
|
|
|
|
|
ue.Portamento = new UstPortamento();
|
|
|
|
|
}
|
|
|
|
|
ue.Portamento.ParseLine( line );
|
|
|
|
|
} else if ( spl[0].Equals( "Envelope" ) ) {
|
|
|
|
|
ue.Envelope = new UstEnvelope( line );
|
|
|
|
|
//PreUtterance=1
|
|
|
|
|
//VoiceOverlap=6
|
|
|
|
|
} else if ( spl[0].Equals( "VoiceOverlap" ) ) {
|
|
|
|
|
if ( spl[1] != "" ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
ue.VoiceOverlap = PortUtil.parseInt( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "PreUtterance" ) ) {
|
|
|
|
|
if ( spl[1] != "" ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
ue.PreUtterance = PortUtil.parseInt( spl[1] );
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
} else if ( spl[0].Equals( "Flags" ) ) {
|
|
|
|
|
ue.Flags = line.Substring( 6 );
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} else {
|
|
|
|
|
#if DEBUG
|
|
|
|
|
PortUtil.println( "UstFile#.ctor; info: don't know how to process this line; line=" + line );
|
|
|
|
|
#endif
|
2009-07-29 10:03:20 -07:00
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
if ( !sr.ready() ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
break;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
line = sr.readLine();
|
2009-09-07 03:44:18 -07:00
|
|
|
|
}
|
|
|
|
|
#if DEBUG
|
|
|
|
|
bocoree.debug.push_log( "(ue==null)=" + (ue == null) );
|
|
|
|
|
#endif
|
|
|
|
|
if ( type == 0 ) {
|
|
|
|
|
type = 1;
|
|
|
|
|
} else if ( type == 1 ) {
|
|
|
|
|
ue.Index = index;
|
|
|
|
|
track.addEvent( ue );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
m_tracks.add( track );
|
|
|
|
|
updateTempoInfo();
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
#if DEBUG
|
|
|
|
|
bocoree.debug.push_log( "ex=" + ex );
|
|
|
|
|
#endif
|
2010-03-16 20:14:08 -07:00
|
|
|
|
} finally {
|
|
|
|
|
if ( sr != null ) {
|
|
|
|
|
try {
|
|
|
|
|
sr.close();
|
|
|
|
|
} catch ( Exception ex2 ) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// vsqの指定したトラックを元に,トラックを1つだけ持つustを構築します
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vsq"></param>
|
|
|
|
|
/// <param name="track_index"></param>
|
|
|
|
|
public UstFile( VsqFile vsq, int track_index ) {
|
|
|
|
|
VsqTrack track = vsq.Track.get( track_index );
|
|
|
|
|
|
|
|
|
|
// デフォルトのテンポ
|
|
|
|
|
if( vsq.TempoTable.size() <= 0 ){
|
|
|
|
|
m_tempo = 120.0f;
|
|
|
|
|
}else{
|
|
|
|
|
m_tempo = (float)(60e6 / (double)vsq.TempoTable.get( 0 ).Tempo);
|
|
|
|
|
}
|
|
|
|
|
updateTempoInfo();
|
|
|
|
|
|
|
|
|
|
// R用音符のテンプレート
|
|
|
|
|
int PBTYPE = 5;
|
|
|
|
|
UstEvent template = new UstEvent();
|
|
|
|
|
template.Lyric = "R";
|
|
|
|
|
template.Note = 60;
|
|
|
|
|
template.PreUtterance = 0;
|
|
|
|
|
template.VoiceOverlap = 0;
|
|
|
|
|
template.Intensity = 100;
|
|
|
|
|
template.Moduration = 0;
|
|
|
|
|
|
|
|
|
|
// 再生秒時をとりあえず無視して,ゲートタイム基準で音符を追加
|
|
|
|
|
UstTrack track_add = new UstTrack();
|
|
|
|
|
int last_clock = 0;
|
|
|
|
|
int index = 0;
|
|
|
|
|
for( Iterator itr = track.getNoteEventIterator(); itr.hasNext(); ){
|
|
|
|
|
VsqEvent item = (VsqEvent)itr.next();
|
|
|
|
|
if( last_clock < item.Clock ){
|
|
|
|
|
// ゲートタイム差あり,Rを追加
|
|
|
|
|
UstEvent itemust = (UstEvent)template.clone();
|
|
|
|
|
itemust.setLength( item.Clock - last_clock );
|
|
|
|
|
itemust.Index = index;
|
|
|
|
|
index++;
|
|
|
|
|
track_add.addEvent( itemust );
|
|
|
|
|
}
|
|
|
|
|
UstEvent item_add = new UstEvent();
|
|
|
|
|
item_add.setLength( item.ID.getLength() );
|
|
|
|
|
item_add.Lyric = item.ID.LyricHandle.L0.Phrase;
|
|
|
|
|
item_add.Note = item.ID.Note;
|
|
|
|
|
item_add.Index = index;
|
|
|
|
|
item_add.Intensity = item.ID.Dynamics;
|
|
|
|
|
item_add.Moduration = item.UstEvent.Moduration;
|
|
|
|
|
item_add.PreUtterance = item.UstEvent.PreUtterance;
|
|
|
|
|
item_add.VoiceOverlap = item.UstEvent.VoiceOverlap;
|
|
|
|
|
index++;
|
|
|
|
|
track_add.addEvent( item_add );
|
|
|
|
|
last_clock = item.Clock + item.ID.getLength();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 再生秒時を無視して,ピッチベンドを追加
|
|
|
|
|
//VsqBPList pbs = track.getCurve( "pbs" );
|
|
|
|
|
//VsqBPList pit = track.getCurve( "pit" );
|
|
|
|
|
int clock = 0;
|
|
|
|
|
for ( Iterator itr = track_add.getNoteEventIterator(); itr.hasNext(); ) {
|
|
|
|
|
UstEvent item = (UstEvent)itr.next();
|
|
|
|
|
int clock_begin = clock;
|
|
|
|
|
int clock_end = clock + item.getLength();
|
|
|
|
|
Vector<Float> pitch = new Vector<Float>();
|
|
|
|
|
boolean allzero = true;
|
|
|
|
|
for ( int cl = clock_begin; cl <= clock_end; cl += PBTYPE ) {
|
|
|
|
|
float pit = (float)track.getPitchAt( cl );
|
|
|
|
|
if ( pit != 0.0 ) {
|
|
|
|
|
allzero = false;
|
|
|
|
|
}
|
|
|
|
|
pitch.add( pit );
|
|
|
|
|
}
|
|
|
|
|
if ( !allzero ) {
|
|
|
|
|
item.Pitches = PortUtil.convertFloatArray( pitch.toArray( new Float[] { } ) );
|
|
|
|
|
item.PBType = PBTYPE;
|
|
|
|
|
} else {
|
|
|
|
|
item.PBType = -1;
|
|
|
|
|
}
|
|
|
|
|
clock += item.getLength();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
|
|
|
|
|
// 再生秒時を考慮して,適時テンポを追加
|
|
|
|
|
//TODO: このへん
|
|
|
|
|
// throw new NotImplementedException();
|
|
|
|
|
|
|
|
|
|
m_tracks.add( track_add );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
private UstFile() {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2009-09-07 03:44:18 -07:00
|
|
|
|
public String getProjectName() {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return m_project_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getBaseTempo() {
|
|
|
|
|
return (int)(6e7 / m_tempo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public double getTotalSec() {
|
|
|
|
|
int max = 0;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
for ( int track = 0; track < m_tracks.size(); track++ ) {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
int count = 0;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
for ( int i = 0; i < m_tracks.get( track ).getEventCount(); i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
count += (int)m_tracks.get( track ).getEvent( i ).getLength();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
max = Math.Max( max, count );
|
|
|
|
|
}
|
|
|
|
|
return getSecFromClock( max );
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-07 03:44:18 -07:00
|
|
|
|
public Vector<TempoTableEntry> getTempoList() {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return m_tempo_table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public UstTrack getTrack( int track ) {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
return m_tracks.get( track );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getTrackCount() {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
return m_tracks.size();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2010-03-16 20:14:08 -07:00
|
|
|
|
/// TempoTableの[*].Timeの部分を更新します
|
2009-06-25 07:16:22 -07:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public void updateTempoInfo() {
|
2009-09-07 03:44:18 -07:00
|
|
|
|
m_tempo_table = new Vector<TempoTableEntry>();
|
|
|
|
|
if ( m_tracks.size() <= 0 ) {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int clock = 0;
|
|
|
|
|
double time = 0.0;
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int last_tempo_clock = 0; //最後にTempo値が代入されていたイベントのクロック
|
|
|
|
|
float last_tempo = m_tempo; //最後に代入されていたテンポの値
|
2009-09-07 03:44:18 -07:00
|
|
|
|
for ( int i = 0; i < m_tracks.get( 0 ).getEventCount(); i++ ) {
|
|
|
|
|
if ( m_tracks.get( 0 ).getEvent( i ).Tempo > 0f ) {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
time += (clock - last_tempo_clock) / (8.0 * last_tempo);
|
2009-09-07 03:44:18 -07:00
|
|
|
|
if ( m_tempo_table.size() == 0 && clock != 0 ) {
|
|
|
|
|
m_tempo_table.add( new TempoTableEntry( 0, (int)(6e7 / m_tempo), 0.0 ) );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
m_tempo_table.add( new TempoTableEntry( clock, (int)(6e7 / m_tracks.get( 0 ).getEvent( i ).Tempo), time ) );
|
|
|
|
|
last_tempo = m_tracks.get( 0 ).getEvent( i ).Tempo;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
last_tempo_clock = clock;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
clock += (int)m_tracks.get( 0 ).getEvent( i ).getLength();
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2010-03-16 20:14:08 -07:00
|
|
|
|
/// 指定したクロックにおける、clock=0からの演奏経過時間(sec)
|
2009-06-25 07:16:22 -07:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="clock"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public double getSecFromClock( int clock ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
int c = m_tempo_table.size();
|
|
|
|
|
for ( int i = c - 1; i >= 0; i-- ) {
|
|
|
|
|
TempoTableEntry item = m_tempo_table.get( i );
|
|
|
|
|
if ( item.Clock < clock ) {
|
|
|
|
|
double init = item.Time;
|
|
|
|
|
int dclock = clock - item.Clock;
|
|
|
|
|
double sec_per_clock1 = item.Tempo * 1e-6 / 480.0;
|
2009-06-25 07:16:22 -07:00
|
|
|
|
return init + dclock * sec_per_clock1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
double sec_per_clock = 0.125 / m_tempo;
|
|
|
|
|
return clock * sec_per_clock;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-07 03:44:18 -07:00
|
|
|
|
public void write( String file ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
BufferedWriter sw = null;
|
|
|
|
|
try {
|
|
|
|
|
sw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file ), "Shift_JIS" ) );
|
|
|
|
|
sw.write( "[#SETTING]" );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "Tempo=" + m_tempo );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "Tracks=1" );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "ProjectName=" + m_project_name );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "VoiceDir=" + m_voice_dir );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "OutFile=" + m_out_file );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "CacheDir=" + m_cache_dir );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "Tool1=" + m_tool1 );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
sw.write( "Tool2=" + m_tool2 );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
UstTrack target = m_tracks.get( 0 );
|
|
|
|
|
int count = target.getEventCount();
|
|
|
|
|
for ( int i = 0; i < count; i++ ) {
|
|
|
|
|
target.getEvent( i ).print( sw );
|
|
|
|
|
}
|
|
|
|
|
sw.write( "[#TRACKEND]" );
|
|
|
|
|
sw.newLine();
|
|
|
|
|
} catch ( Exception ex ) {
|
|
|
|
|
} finally {
|
|
|
|
|
if ( sw != null ) {
|
|
|
|
|
try {
|
|
|
|
|
sw.close();
|
|
|
|
|
} catch ( Exception ex2 ) {
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
public Object clone() {
|
2009-06-25 07:16:22 -07:00
|
|
|
|
UstFile ret = new UstFile();
|
|
|
|
|
ret.m_tempo = m_tempo;
|
|
|
|
|
ret.m_project_name = m_project_name;
|
|
|
|
|
ret.m_voice_dir = m_voice_dir;
|
|
|
|
|
ret.m_out_file = m_out_file;
|
|
|
|
|
ret.m_cache_dir = m_cache_dir;
|
|
|
|
|
ret.m_tool1 = m_tool1;
|
|
|
|
|
ret.m_tool2 = m_tool2;
|
2009-09-07 03:44:18 -07:00
|
|
|
|
for ( int i = 0; i < m_tracks.size(); i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
ret.m_tracks.set( i, (UstTrack)m_tracks.get( i ).clone() );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2009-09-07 03:44:18 -07:00
|
|
|
|
ret.m_tempo_table = new Vector<TempoTableEntry>();
|
|
|
|
|
for ( int i = 0; i < m_tempo_table.size(); i++ ) {
|
2010-03-16 20:14:08 -07:00
|
|
|
|
ret.m_tempo_table.add( (TempoTableEntry)m_tempo_table.get( i ).clone() );
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
|
|
|
|
|
#if !JAVA
|
|
|
|
|
public object Clone() {
|
|
|
|
|
return clone();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#if !JAVA
|
2009-06-25 07:16:22 -07:00
|
|
|
|
}
|
2010-03-16 20:14:08 -07:00
|
|
|
|
#endif
|