Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Xian55 committed Apr 30, 2023
1 parent e98b528 commit 23f7628
Show file tree
Hide file tree
Showing 24 changed files with 2,580 additions and 0 deletions.
7 changes: 7 additions & 0 deletions App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Application x:Class="Protonox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>

</Application.Resources>
</Application>
147 changes: 147 additions & 0 deletions App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.Windows;
using System.CommandLine;

using Microsoft.Extensions.DependencyInjection;

using Protonox.Labs.Api;

using Tesseract;
using Protonox.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Parsing;

using Serilog;
using Microsoft.Extensions.Logging;

namespace Protonox
{
public sealed partial class App : Application
{
public App()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File("log_.txt",
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true)
.CreateLogger();

Log.Logger.Information("[Startup]");
}

private static void ConfigureServices(ServiceCollection services)
{
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.ClearProviders().AddSerilog();
});
services.AddSingleton(loggerFactory.CreateLogger(nameof(App)));

services.AddSingleton<ElevenLabs>();

services.AddSingleton<VoiceSettings>();

services.AddSingleton<TesseractEngine>(x =>
CreateTesseractEngine(x.GetRequiredService<TesseractCLIArgs>()));

services.AddSingleton<AudioSettings>();

services.AddSingleton<Controller>();
services.AddSingleton<Window1>();
}

public static TesseractEngine CreateTesseractEngine(TesseractCLIArgs args)
{
Log.Logger.Information($"[Startup] Tesseract Path: `{args.Path}` | Lang: `{args.Lang}`");
return new TesseractEngine(args.Path, args.Lang, EngineMode.Default);
}

protected override void OnStartup(StartupEventArgs e)
{
ServiceCollection services = new();

int errorCount = ProcessCLI(services, e.Args);
if (errorCount > 0)
{
Current.Shutdown();
return;
}

ConfigureServices(services);

var serviceProvider = services.BuildServiceProvider();

var mainWindow = serviceProvider.GetRequiredService<Window1>();
mainWindow.Show();
}

private int ProcessCLI(ServiceCollection services, string[] args)
{
var apiKey = new Argument<string>("apikey", "ElevenLabs API key");

var userAgent = new Option<string>(
new[] { "--userAgent", "-ua" },
() => { return null; }, "Either: 'rand' or UserAgent");

var proxy = new Option<string>(
new[] { "--proxy", "-p" },
() => { return null; }, "Either: 'rand' or Proxy as format PROTOCOL://ADDRESS:PORT");

var lang = new Option<string>(
new[] { "--lang", "-l" },
() => { return "eng"; }, "Tesseract Language model file name without extension.");

var tessPath = new Option<string>(
new[] { "--tpath", "-t" },
() => { return @".\tessdata"; }, "Tesseract Language model path.");

var rootCommand = new RootCommand() {
apiKey,
userAgent,
proxy,
lang,
tessPath
};

rootCommand.SetHandler(
ProcessArgs,
apiKey,
proxy,
userAgent,
lang,
tessPath
);

var parser = new CommandLineBuilder(rootCommand)
.UseDefaults()
.Build();

var result = parser.Parse(args);

if (result.Errors.Count == 0)
parser.Invoke(args);

foreach (var error in result.Errors)
Log.Logger.Error(error.Message);

return result.Errors.Count;

void ProcessArgs(string apiKey, string proxy, string userAgent, string lang, string tPath)
{
services.AddScoped((x) => new ElevenLabsCLIArgs
{
ApiKey = apiKey,
Proxy = proxy,
UserAgent = userAgent
});

services.AddScoped((x) => new TesseractCLIArgs
{
Lang = lang,
Path = tPath
});
}
}
}
}
11 changes: 11 additions & 0 deletions Audio/AudioSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Protonox
{
public sealed class AudioSettings
{
public float Volume { get; set; }
public string Voice { get; set; }

public float Similarity { get; set; }
public float Stability { get; set; }
}
}
9 changes: 9 additions & 0 deletions CommandLine/ElevenLabsCLIArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Protonox.CommandLine
{
public sealed class ElevenLabsCLIArgs
{
public required string ApiKey { get; set; }
public required string UserAgent { get; set; }
public required string Proxy { get; set; }
}
}
8 changes: 8 additions & 0 deletions CommandLine/TesseractCLIArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Protonox.CommandLine
{
public sealed class TesseractCLIArgs
{
public required string Lang { get; set; }
public required string Path { get; set; }
}
}
113 changes: 113 additions & 0 deletions Controller/Controller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Extensions.Logging;

using NAudio.Wave;

using Protonox.Labs.Api;

using Serilog.Core;

using Tesseract;

namespace Protonox
{
public sealed class Controller
{
private readonly ILogger logger;
private readonly ElevenLabs labs;
private readonly VoiceSettings voiceSettings;
private readonly AudioSettings audioSettings;

private readonly TesseractEngine ocr;

public Controller(ILogger logger, ElevenLabs labs, VoiceSettings settings,
AudioSettings audioSettings, TesseractEngine ocr)
{
this.logger = logger;
this.labs = labs;
this.voiceSettings = settings;

this.audioSettings = audioSettings;

this.ocr = ocr;
}

public static void Shutdown()
{
System.Windows.Application.Current.Shutdown();
}

public int GenAudioHash(string text) =>
HashCode.Combine(audioSettings.Voice.DetHashGen(),
text.DetHashGen(),
voiceSettings.GetHashCode());

public string AudioOutput(string text)
{
UpdateVoiceSettings();
return Path.Combine(labs.Output,
GenAudioHash(text).ToString() + ElevenLabs.EXT);
}

public string StartOCRThread(Rectangle rect)
{
string text = string.Empty;

Thread thread = new(process);
thread.Start();
thread.Join();

logger.LogInformation($"[OCR] {text}");

return text;
void process() => text = Extract(rect);
}

private string Extract(Rectangle rect)
{
using Bitmap bitmap = Screenshot.Get(rect.Location, rect);

using var page = ocr.Process(bitmap);

return page.GetText().Trim();
}

public void Playback(string filePath)
{
AudioFileReader reader = new(filePath)
{
Volume = audioSettings.Volume
};

WaveOut wavePlayer = new();
wavePlayer.Init(reader);
wavePlayer.Play();
}

public Task<Voices[]> GetInitVoices()
{
return labs.GetInitVoices();
}

public async Task<bool> PostTTS(string text)
{
UpdateVoiceSettings();

Voices voice = labs.Voices[audioSettings.Voice];

return await labs.PostTTS(voice.voice_id,
text, voiceSettings, GenAudioHash(text));
}

public void UpdateVoiceSettings()
{
voiceSettings.similarity_boost = audioSettings.Similarity;
voiceSettings.stability = audioSettings.Stability;
}
}
}
16 changes: 16 additions & 0 deletions Extensions/Screenshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Drawing;

namespace Protonox
{
public static class Screenshot
{
public static Bitmap Get(Point source, Rectangle targetRectangle)
{
Bitmap bitmap = new(targetRectangle.Width, targetRectangle.Height);
using Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(source, Point.Empty, targetRectangle.Size);

return bitmap;
}
}
}
18 changes: 18 additions & 0 deletions Extensions/StringExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Protonox
{
public static class StringExtension
{
public static int DetHashGen(this string text)
{
unchecked
{
int hash = 23;
foreach (char c in text)
{
hash = hash * 31 + c;
}
return hash;
}
}
}
}
Binary file added Images/UI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions Labs/Api/Voices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;

namespace Protonox.Labs.Api
{
public sealed class VoicesArray
{
public Voices[] voices { get; set; }
}

public sealed class Voices
{
public string voice_id { get; set; }
public string name { get; set; }
public object samples { get; set; }
public string category { get; set; }
public Fine_Tuning fine_tuning { get; set; }
public Labels labels { get; set; }
public string description { get; set; }
public string preview_url { get; set; }
public object[] available_for_tiers { get; set; }
public VoiceSettings settings { get; set; }
}

public sealed class Fine_Tuning
{
public object model_id { get; set; }
public bool is_allowed_to_fine_tune { get; set; }
public bool fine_tuning_requested { get; set; }
public string finetuning_state { get; set; }
public object verification_attempts { get; set; }
public object[] verification_failures { get; set; }
public int verification_attempts_count { get; set; }
public object slice_ids { get; set; }
}

public sealed class Labels
{
}

public sealed class VoiceSettings
{
public float stability { get; set; } = 0.75f;
public float similarity_boost { get; set; } = 0.75f;

public override int GetHashCode()
{
return HashCode.Combine(stability, similarity_boost);
}
}

public sealed class TTS_Body
{
public string text { get; set; }
public VoiceSettings voice_settings { get; set; }
}
}
Loading

0 comments on commit 23f7628

Please sign in to comment.