Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion OpenUtau/Strings/Strings.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
<system:String x:Key="dialogs.messagebox.yes">Yes</system:String>
<system:String x:Key="dialogs.noresampler.caption">No resampler</system:String>
<system:String x:Key="dialogs.noresampler.message">No resampler! Put your favourite resampler exe or dll in the Resamplers folder and choose it in Preferences!</system:String>
<system:String x:Key="dialogs.remaptimeaxis.message">This tool will change the tempo of the project without changing the actual positions and durations (in seconds) of notes.
New BPM:</system:String>
<system:String x:Key="dialogs.unsupportedfile.caption">Unsupported file format</system:String>
<system:String x:Key="dialogs.unsupportedfile.message">Unsupported file format: </system:String>
<system:String x:Key="dialogs.timesig.caption">Time Signature</system:String>
<system:String x:Key="dialogs.tracksettings.caption">Track Settings</system:String>
<system:String x:Key="dialogs.tracksettings.location">Location</system:String>
Expand Down Expand Up @@ -154,6 +158,9 @@
<system:String x:Key="menu.help.logslocation">Open Logs Location</system:String>
<system:String x:Key="menu.help.reportissue">Report Issue</system:String>
<system:String x:Key="menu.help.wiki">OpenUtau Wiki</system:String>
<system:String x:Key="menu.project">Project</system:String>
<system:String x:Key="menu.project.expressions">Expressions...</system:String>
<system:String x:Key="menu.project.remaptimeaxis">Adjust Tempo (Preserve Timing)</system:String>
<system:String x:Key="menu.tools">Tools</system:String>
<system:String x:Key="menu.tools.clearcache">Clear Cache</system:String>
<system:String x:Key="menu.tools.debugwindow">Debug Window</system:String>
Expand All @@ -166,7 +173,6 @@
<system:String x:Key="menu.tools.layout.vsplit12">Vertical 1:2</system:String>
<system:String x:Key="menu.tools.layout.vsplit13">Vertical 1:3</system:String>
<system:String x:Key="menu.tools.prefs">Preferences...</system:String>
<system:String x:Key="menu.tools.project.expressions">Expressions...</system:String>
<system:String x:Key="menu.tools.singer.install">Install Singer...</system:String>
<system:String x:Key="menu.tools.singer.installadv">Install Singer (Advanced)...</system:String>
<system:String x:Key="menu.tools.singers">Singers...</system:String>
Expand Down
55 changes: 55 additions & 0 deletions OpenUtau/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive;
Expand Down Expand Up @@ -262,6 +263,60 @@ public void RefreshTimelineContextMenu(int tick) {
}
}

/// <summary>
/// Remap a tick position from the old time axis to the new time axis without changing its absolute position (in ms).
/// Note that this can only be used on positions, not durations.
/// </summary>
private int RemapTickPos(int tickPos, TimeAxis oldTimeAxis, TimeAxis newTimeAxis){
double msPos = oldTimeAxis.TickPosToMsPos(tickPos);
return newTimeAxis.MsPosToTickPos(msPos);
}

/// <summary>
/// Remap the starting and ending positions of all the notes and parts in the whole project
/// from the old time axis to the new time axis, without changing their absolute positions in ms.
/// </summary>
public void RemapTimeAxis(TimeAxis oldTimeAxis, TimeAxis newTimeAxis){
var project = DocManager.Inst.Project;
foreach(var part in project.parts){
var partOldStartTick = part.position;
var partNewStartTick = RemapTickPos(part.position, oldTimeAxis, newTimeAxis);
if(partNewStartTick != partOldStartTick){
DocManager.Inst.ExecuteCmd(new MovePartCommand(
project, part, partNewStartTick, part.trackNo));
}
if(part is UVoicePart voicePart){
var partOldEndTick = voicePart.End;
var partNewEndTick = RemapTickPos(voicePart.End, oldTimeAxis, newTimeAxis);
if(partNewEndTick - partNewStartTick != voicePart.Duration){
DocManager.Inst.ExecuteCmd(new ResizePartCommand(
project, voicePart, partNewEndTick - partNewStartTick));
}
var noteCommands = new List<UCommand>();
foreach(var note in voicePart.notes){
var noteOldStartTick = note.position + partOldStartTick;
var noteOldEndTick = note.End + partOldStartTick;
var noteOldDuration = note.duration;
var noteNewStartTick = RemapTickPos(noteOldStartTick, oldTimeAxis, newTimeAxis);
var noteNewEndTick = RemapTickPos(noteOldEndTick, oldTimeAxis, newTimeAxis);
var deltaPosTickInPart = (noteNewStartTick - partNewStartTick) - (noteOldStartTick - partOldStartTick);
if(deltaPosTickInPart != 0){
noteCommands.Add(new MoveNoteCommand(voicePart, note, deltaPosTickInPart, 0));
}
var noteNewDuration = noteNewEndTick - noteNewStartTick;
var deltaDur = noteNewDuration - noteOldDuration;
if(deltaDur != 0){
noteCommands.Add(new ResizeNoteCommand(voicePart, note, deltaDur));
}
//TODO: expression curve remapping, phoneme timing remapping
}
foreach(var command in noteCommands){
DocManager.Inst.ExecuteCmd(command);
}
}
}
}

#region ICmdSubscriber

public void OnNext(UCommand cmd, bool isUndo) {
Expand Down
5 changes: 4 additions & 1 deletion OpenUtau/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
</MenuItem>
<MenuItem Header="{DynamicResource menu.file.openexportlocation}" Click="OnMenuOpenProjectLocation"/>
</MenuItem>
<MenuItem Header="{DynamicResource menu.project}">
<MenuItem Header="{DynamicResource menu.project.expressions}" Click="OnMenuExpressionss"/>
<MenuItem Header="{DynamicResource menu.project.remaptimeaxis}" Click="OnMenuRemapTimeaxis"/>
</MenuItem>
<MenuItem Header="{DynamicResource menu.tools}">
<MenuItem Header="{DynamicResource menu.tools.layout}">
<MenuItem Header="{DynamicResource menu.tools.layout.vsplit11}" Click="OnMenuLayoutVSplit11"/>
Expand All @@ -79,7 +83,6 @@
<MenuItem Header="{Binding ClearCacheHeader}" Click="OnMenuClearCache"/>
<MenuItem Header="{DynamicResource menu.tools.debugwindow}" Click="OnMenuDebugWindow"/>
<MenuItem Header="{DynamicResource phoneticassistant.caption}" Click="OnMenuPhoneticAssistant"/>
<MenuItem Header="{DynamicResource menu.tools.project.expressions}" Click="OnMenuExpressionss"/>
<MenuItem Header="{DynamicResource menu.tools.singers}" Click="OnMenuSingers"/>
<MenuItem Header="{DynamicResource menu.tools.singer.install}" Click="OnMenuInstallSinger"/>
<MenuItem Header="{DynamicResource menu.tools.dependency.install}" Click="OnMenuInstallDependency"/>
Expand Down
32 changes: 32 additions & 0 deletions OpenUtau/Views/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,38 @@ private void DelTempoChange(int tick) {
DocManager.Inst.EndUndoGroup();
}



void OnMenuRemapTimeaxis(object sender, RoutedEventArgs e){
var project = DocManager.Inst.Project;
var dialog = new TypeInDialog {
Title = ThemeManager.GetString("menu.project.remaptimeaxis")
};
dialog.Height = 200;
dialog.SetPrompt(ThemeManager.GetString("dialogs.remaptimeaxis.message"));
dialog.SetText(project.tempos[0].bpm.ToString());
dialog.onFinish = s => {
try{
if (double.TryParse(s, out double bpm)) {
DocManager.Inst.StartUndoGroup();
var oldTimeAxis = project.timeAxis.Clone();
DocManager.Inst.ExecuteCmd(new BpmCommand(
project, bpm));
foreach(var tempo in project.tempos.Skip(1)){
DocManager.Inst.ExecuteCmd(new DelTempoChangeCommand(
project, tempo.position));
}
viewModel.RemapTimeAxis(oldTimeAxis, project.timeAxis.Clone());
DocManager.Inst.EndUndoGroup();
}
} catch (Exception e) {
Log.Error(e, "Failed to open project location.");
MessageBox.ShowError(this, e);
}
};
dialog.ShowDialog(this);
}

private void AddTimeSigChange(int bar) {
var project = DocManager.Inst.Project;
var timeSig = project.timeAxis.TimeSignatureAtBar(bar);
Expand Down
1 change: 1 addition & 0 deletions OpenUtau/Views/TypeInDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Title="TypeInDialog" Height="120" Width="320" WindowStartupLocation="CenterOwner"
ExtendClientAreaToDecorationsHint="False">
<StackPanel VerticalAlignment="Center" Margin="{Binding $parent.WindowDecorationMargin}">
<TextBlock Margin="20" Name="Prompt" IsVisible="False" TextWrapping="Wrap" MaxWidth="560"/>
<TextBox Name="TextBox" Margin="4"/>
<Button Name="OkButton" Content="OK" Margin="4" HorizontalAlignment="Stretch"/>
</StackPanel>
Expand Down
5 changes: 5 additions & 0 deletions OpenUtau/Views/TypeInDialog.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public TypeInDialog() {
OkButton.Click += OkButtonClick;
}

public void SetPrompt(string prompt) {
Prompt.IsVisible = true;
Prompt.Text = prompt;
}

public void SetText(string text) {
TextBox.Text = text;
}
Expand Down