Skip to content
Open
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
7 changes: 5 additions & 2 deletions OpenUtau.Core/Classic/ExeResampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace OpenUtau.Classic {
internal class ExeResampler : IResampler {
public string Name { get; private set; }
public string FilePath { get; private set; }
public bool CallDirectly { get; private set; }
public bool isLegalPlugin => _isLegalPlugin;
public ResamplerManifest Manifest { get; private set; }
readonly string _name;
Expand Down Expand Up @@ -65,10 +66,12 @@ public ExeResampler(string filePath, string basePath) {
_name = Path.GetRelativePath(basePath, filePath);
_isLegalPlugin = true;
}
//Check if should use wine
//Since we can't call Linux/MacOS native resamplers in wine, we need call them directly
string ext = Path.GetExtension(filePath).ToLower();
CallDirectly = ext != ".exe" && ext != ".bat";
//Check if should use wine
winePath = Preferences.Default.WinePath;
useWine = !OS.IsWindows() && !string.IsNullOrEmpty(winePath) && (ext == ".exe" || ext == ".bat");
useWine = !string.IsNullOrEmpty(winePath) && !CallDirectly;
//Load Resampler Manifest
Manifest = LoadManifest();
//Make moresampler happy
Expand Down
20 changes: 5 additions & 15 deletions OpenUtau.Core/Classic/ExeWavtool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@ public ExeWavtool(string filePath, string basePath) {
this.filePath = filePath;
name = Path.GetRelativePath(basePath, filePath);
osEncoding = OS.IsWindows() ? Encoding.GetEncoding(0) : Encoding.UTF8;
string ext = Path.GetExtension(filePath).ToLower();
winePath = Preferences.Default.WinePath;
useWine = !OS.IsWindows() && !string.IsNullOrEmpty(winePath) && (ext == ".exe" || ext == ".bat");
useWine = !string.IsNullOrEmpty(winePath);
}

public float[] Concatenate(List<ResamplerItem> resamplerItems, string tempPath, CancellationTokenSource cancellation) {
if (cancellation.IsCancellationRequested) {
return null;
}
//The builtin worldline resampler can't be called from bat script,
//so we need to call it directly from C#
//The builtin worldline and Linux/MacOS resamplers can't be
//called from bat script, so we need to call it directly from C#
foreach(var item in resamplerItems){
if(!(item.resampler is ExeResampler) && !cancellation.IsCancellationRequested && !File.Exists(item.outputFile)){
if(item.resampler.CallDirectly && !cancellation.IsCancellationRequested && !File.Exists(item.outputFile)){
lock (Renderers.GetCacheLock(item.outputFile)) {
item.resampler.DoResamplerReturnsFile(item, Log.Logger);
}
Expand Down Expand Up @@ -218,16 +217,7 @@ string ConvertToWindowsPath (string linuxPath) {
return windowsPath;
}

[DllImport("libc", SetLastError = true)]
private static extern int chmod(string pathname, int mode);

public void CheckPermissions() {
if (OS.IsWindows() || !File.Exists(filePath)) {
return;
}
int mode = (7 << 6) | (5 << 3) | 5;
chmod(filePath, mode);
}
public void CheckPermissions() { }

public override string ToString() => name;
}
Expand Down
1 change: 1 addition & 0 deletions OpenUtau.Core/Classic/IResampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace OpenUtau.Classic {
public interface IResampler {
string FilePath { get; }
bool CallDirectly { get; }
float[] DoResampler(ResamplerItem args, ILogger logger);
string DoResamplerReturnsFile(ResamplerItem args, ILogger logger);
void CheckPermissions();
Expand Down
2 changes: 1 addition & 1 deletion OpenUtau.Core/Classic/ToolsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ IWavtool LoadWavtool(string filePath, string basePath) {
return new ExeWavtool(filePath, basePath);
}
if (!OS.IsWindows() && (ext == ".sh" || string.IsNullOrEmpty(ext))) {
return new ExeWavtool(filePath, basePath);
return new UnixWavtool(filePath, basePath);
}
return null;
}
Expand Down
110 changes: 110 additions & 0 deletions OpenUtau.Core/Classic/UnixWavtool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using NAudio.Wave;
using OpenUtau.Core;
using OpenUtau.Core.Render;
using OpenUtau.Core.Util;
using Serilog;

namespace OpenUtau.Classic {
class UnixWavtool : IWavtool {
readonly StringBuilder sb = new StringBuilder();
readonly string filePath;
readonly string name;

public UnixWavtool(string filePath, string basePath) {
this.filePath = filePath;
name = Path.GetRelativePath(basePath, filePath);
}

public float[] Concatenate(List<ResamplerItem> resamplerItems, string tempPath, CancellationTokenSource cancellation) {
if (cancellation.IsCancellationRequested) {
return null;
}

File.Delete(tempPath);

foreach(var item in resamplerItems){
if(!File.Exists(item.outputFile)){
lock (Renderers.GetCacheLock(item.outputFile)) {
item.resampler.DoResamplerReturnsFile(item, Log.Logger);
}
}

string parameters = GenerateParameters(item, tempPath);

ProcessRunner.Run(filePath, parameters, Log.Logger, workDir: PathManager.Inst.CachePath, timeoutMs: 5 * 60 * 1000);
}

string whdFile = tempPath + ".whd";
string datFile = tempPath + ".dat";

if (File.Exists(whdFile) && File.Exists(datFile)) {
using (var outStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write))
{
foreach (string file in new[] { whdFile, datFile })
{
using (var inStream = new FileStream(file, FileMode.Open, FileAccess.Read))
{
inStream.CopyTo(outStream);
}
}
}

File.Delete(whdFile);
File.Delete(datFile);
}

if (string.IsNullOrEmpty(tempPath) || File.Exists(tempPath)) {
using (var wavStream = Core.Format.Wave.OpenFile(tempPath)) {
return Core.Format.Wave.GetSamples(wavStream.ToSampleProvider().ToMono(1, 0));
}
}
return new float[0];
}

string GenerateParameters(ResamplerItem item, string tempPath) {
string envelope = GetEnvelope(item);
string dur = $"{item.phone.duration:G999}@{item.phone.adjustedTempo:G999}{(item.durCorrection >= 0 ? "+" : "")}{item.durCorrection}";

if (item.phone.direct) {
return $"\"{tempPath}\" \"{item.outputFile}\" {item.offset} {item.phone.durationMs:F1} {envelope}";
}

return $"\"{tempPath}\" \"{item.outputFile}\" {item.skipOver} {dur} {envelope}";
}

string GetEnvelope(ResamplerItem item) {
var env = item.phone.envelope;
sb.Clear()
.Append(env[0].X - env[0].X).Append(' ')
.Append(env[1].X - env[0].X).Append(' ')
.Append(env[4].X - env[3].X).Append(' ')
.Append(env[0].Y).Append(' ')
.Append(env[1].Y).Append(' ')
.Append(env[3].Y).Append(' ')
.Append(env[4].Y).Append(' ')
.Append(item.overlap).Append(' ')
.Append(env[4].X - env[4].X).Append(' ')
.Append(env[2].X - env[1].X).Append(' ')
.Append(env[2].Y);
return sb.ToString();
}

[DllImport("libc", SetLastError = true)]
private static extern int chmod(string pathname, int mode);

public void CheckPermissions() {
if (OS.IsWindows() || !File.Exists(filePath)) {
return;
}
int mode = (7 << 6) | (5 << 3) | 5;
chmod(filePath, mode);
}

public override string ToString() => name;
}
}
2 changes: 2 additions & 0 deletions OpenUtau.Core/Classic/WorldlineResampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ namespace OpenUtau.Classic {
internal class WorldlineResampler : IResampler {
public const string name = "worldline";
public string FilePath { get; private set; }
public bool CallDirectly { get; private set; }

public WorldlineResampler() {
string ext = OS.IsWindows() ? ".dll" : OS.IsMacOS() ? ".dylib" : ".so";
FilePath = Path.Join(PathManager.Inst.RootPath, name + ext);
CallDirectly = true;
}

public float[] DoResampler(ResamplerItem item, ILogger logger) {
Expand Down
1 change: 1 addition & 0 deletions OpenUtau.Core/Util/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ private static void Load() {
if (!ValidString(new Action(() => CultureInfo.GetCultureInfo(Default.SortingOrder)))) Default.SortingOrder = string.Empty;
if (!Renderers.getRendererOptions().Contains(Default.DefaultRenderer)) Default.DefaultRenderer = string.Empty;
if (!Onnx.getRunnerOptions().Contains(Default.OnnxRunner)) Default.OnnxRunner = string.Empty;
if (OS.IsWindows()) Default.WinePath = string.Empty;
if (Default.Theme != null) {
Default.ThemeName = Default.Theme switch {
1 => "Dark",
Expand Down
Loading