Skip to content

Commit

Permalink
Merge pull request #853 from lottev1991/PlaySampleOnClick
Browse files Browse the repository at this point in the history
[Singer window] Play sample on click + [Wave.cs] Support reading AIFF format
  • Loading branch information
stakira authored Oct 2, 2023
2 parents 819ca7a + d8c8a74 commit 43d5431
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 3 deletions.
1 change: 1 addition & 0 deletions OpenUtau.Core/Classic/ClassicSinger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class ClassicSinger : USinger {
public override float PortraitOpacity => voicebank.PortraitOpacity;
public override int PortraitHeight => voicebank.PortraitHeight;
public override string DefaultPhonemizer => voicebank.DefaultPhonemizer;
public override string Sample => voicebank.Sample == null ? null : Path.Combine(Location, voicebank.Sample);
public override Encoding TextFileEncoding => voicebank.TextFileEncoding;
public override IList<USubbank> Subbanks => subbanks;
public override IList<UOto> Otos => otos;
Expand Down
2 changes: 2 additions & 0 deletions OpenUtau.Core/Classic/VoiceBank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class Voicebank {
public string Voice;
public string Web;
public string Version;
public string Sample;
public string OtherInfo;
public string DefaultPhonemizer;
public Encoding TextFileEncoding;
Expand All @@ -34,6 +35,7 @@ public void Reload() {
Voice = null;
Web = null;
Version = null;
Sample = null;
OtherInfo = null;
TextFileEncoding = null;
SingerType = USingerType.Classic;
Expand Down
1 change: 1 addition & 0 deletions OpenUtau.Core/Classic/VoicebankConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class VoicebankConfig {
public string Voice;
public string Web;
public string Version;
public string Sample;
public string DefaultPhonemizer;
public SymbolSet SymbolSet { get; set; }
public Subbank[] Subbanks { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions OpenUtau.Core/Classic/VoicebankLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public static void ParseCharacterTxt(Voicebank voicebank, Stream stream, string
} else if (s[0].StartsWith("voice") || s[0] == "cv") {
voicebank.Voice = s[1];
} else if (s[0] == "sample") {
voicebank.Sample = s[1];
} else if (s[0] == "web") {
voicebank.Web = s[1];
} else if (s[0] == "version") {
Expand Down Expand Up @@ -201,6 +202,9 @@ public static void ApplyConfig(Voicebank bank, VoicebankConfig bankConfig) {
if (!string.IsNullOrWhiteSpace(bankConfig.Version)) {
bank.Version = bankConfig.Version;
}
if (!string.IsNullOrWhiteSpace(bankConfig.Sample)) {
bank.Sample = bankConfig.Sample;
}
if (!string.IsNullOrWhiteSpace(bankConfig.DefaultPhonemizer)) {
bank.DefaultPhonemizer = bankConfig.DefaultPhonemizer;
}
Expand Down
7 changes: 7 additions & 0 deletions OpenUtau.Core/Enunu/EnunuSinger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class EnunuSinger : USinger {
public override string Portrait => voicebank.Portrait == null ? null : Path.Combine(Location, voicebank.Portrait);
public override float PortraitOpacity => voicebank.PortraitOpacity;
public override int PortraitHeight => voicebank.PortraitHeight;
public override string Sample => voicebank.Sample == null ? null : Path.Combine(Location, voicebank.Sample);
public override string DefaultPhonemizer => voicebank.DefaultPhonemizer;
public override Encoding TextFileEncoding => voicebank.TextFileEncoding;
public override IList<USubbank> Subbanks => subbanks;
Expand Down Expand Up @@ -190,5 +191,11 @@ public override byte[] LoadPortrait() {
? null
: File.ReadAllBytes(Portrait);
}

public override byte[] LoadSample() {
return string.IsNullOrEmpty(Sample)
? null
: File.ReadAllBytes(Sample);
}
}
}
3 changes: 3 additions & 0 deletions OpenUtau.Core/Format/Wave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public static WaveStream OpenFile(string filepath) {
if (tag == "fLaC") {
return new FlacReader(filepath);
}
if (ext == ".aiff" || ext == ".aif" || ext == ".aifc") {
return new AiffFileReader(filepath);
}
throw new Exception("Unsupported audio file format.");
}

Expand Down
2 changes: 2 additions & 0 deletions OpenUtau.Core/Ustx/USinger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ public class USinger : INotifyPropertyChanged {
public virtual string Portrait { get; }
public virtual float PortraitOpacity { get; }
public virtual int PortraitHeight { get; }
public virtual string Sample { get; }
public virtual string DefaultPhonemizer { get; }
public virtual Encoding TextFileEncoding => Encoding.UTF8;
public virtual IList<USubbank> Subbanks { get; }
Expand Down Expand Up @@ -246,6 +247,7 @@ public virtual bool TryGetMappedOto(string phoneme, int tone, string color, out

public virtual IEnumerable<UOto> GetSuggestions(string text) { return emptyOtos; }
public virtual byte[] LoadPortrait() => null;
public virtual byte[] LoadSample() => null;
public override string ToString() => Name;

public static USinger CreateMissing(string name) {
Expand Down
2 changes: 2 additions & 0 deletions OpenUtau.Test/Classic/VoicebankConfigTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static VoicebankConfig CreateConfig() {
return new VoicebankConfig() {
PortraitOpacity = 0.75f,
PortraitHeight = 675,
Sample = "sample.wav",
SymbolSet = new SymbolSet() {
Preset = SymbolSetPreset.hiragana,
},
Expand Down Expand Up @@ -55,6 +56,7 @@ public void SerializationTest() {
//"" evaluates to " in verbatim string literals
Assert.Equal(@"portrait_opacity: 0.75
portrait_height: 675
sample: sample.wav
symbol_set:
preset: hiragana
head: '-'
Expand Down
1 change: 1 addition & 0 deletions OpenUtau/Strings/Strings.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@
<system:String x:Key="singers.otoview.showall">Show All</system:String>
<system:String x:Key="singers.otoview.zoomin">Zoom In</system:String>
<system:String x:Key="singers.otoview.zoomout">Zoom Out</system:String>
<system:String x:Key="singers.playsample">Play sample</system:String>
<system:String x:Key="singers.refresh">Refresh</system:String>
<system:String x:Key="singers.setdefaultphonemizer">Set Default Phonemizer</system:String>
<system:String x:Key="singers.setencoding">Set Encoding</system:String>
Expand Down
10 changes: 7 additions & 3 deletions OpenUtau/Views/SingersDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="640"
x:Class="OpenUtau.App.Views.SingersDialog"
Icon="/Assets/open-utau.ico"
Title="{DynamicResource singers.caption}" Width="1000" MinWidth="800" MinHeight="640"
Title="{DynamicResource singers.caption}" Width="1000" MinWidth="850" MinHeight="640"
WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="False" KeyDown="OnKeyDown">
<Design.DataContext>
Expand All @@ -28,9 +28,9 @@
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*" MinWidth="495"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*" MinWidth="340"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" Source="{Binding Avatar}"/>
<ComboBox Grid.Row="0" x:Name="name" HorizontalAlignment="Stretch" Margin="120,10,0,0" VerticalAlignment="Top"
Expand Down Expand Up @@ -94,6 +94,10 @@
<TextBox Text="{Binding SearchAlias}" Watermark="{DynamicResource singers.editoto.searchalias}" Margin="0"
MinWidth="160" HorizontalAlignment="Stretch" Focusable="True" IsVisible="{Binding UseSearchAlias}" />
</StackPanel>
<StackPanel Grid.Row="0" Spacing="5" Margin="0,0,0,0" Height="20"
Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Margin="0" Content="{DynamicResource singers.playsample}" Click="OnPlaySample"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2" Spacing="10" Margin="0" Height="20"
Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<Button Margin="0" Content="{DynamicResource singers.editoto.reset}" Command="{Binding RefreshSinger}"
Expand Down
53 changes: 53 additions & 0 deletions OpenUtau/Views/SingersDialog.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using NAudio.Wave;
using NWaves.Audio;
using OpenUtau.App.ViewModels;
using OpenUtau.Core;
using OpenUtau.Core.Format;
using OpenUtau.Core.Ustx;
using Serilog;

Expand All @@ -27,6 +30,11 @@ public SingersDialog() {
protected override void OnClosed(EventArgs e) {
base.OnClosed(e);
DocManager.Inst.RemoveSubscriber(this);
var playBack = PlaybackManager.Inst.AudioOutput;
var playbackState = playBack.PlaybackState;
if (playbackState == PlaybackState.Playing) {
playBack.Stop();
}
}

void OnSingerMenuButton(object sender, RoutedEventArgs args) {
Expand Down Expand Up @@ -106,11 +114,21 @@ async void OnEditSubbanksButton(object sender, RoutedEventArgs args) {
var dialog = new EditSubbanksDialog();
dialog.ViewModel.SetSinger(viewModel.Singer!);
dialog.RefreshSinger = () => viewModel.RefreshSinger();
var playBack = PlaybackManager.Inst.AudioOutput;
var playbackState = playBack.PlaybackState;
if (playbackState == PlaybackState.Playing) {
playBack.Stop();
}
await dialog.ShowDialog(this);
}

void OnSelectedSingerChanged(object sender, SelectionChangedEventArgs e) {
OtoPlot.WaveFile = null;
var playBack = PlaybackManager.Inst.AudioOutput;
var playbackState = playBack.PlaybackState;
if (playbackState == PlaybackState.Playing) {
playBack.Stop();
}
}

void OnSelectedOtoChanged(object sender, SelectionChangedEventArgs e) {
Expand Down Expand Up @@ -191,6 +209,41 @@ private void OpenInVLabeler(USinger singer, UOto? oto) {
}
}

public void OnPlaySample(object sender, RoutedEventArgs e) {
var viewModel = (DataContext as SingersViewModel)!;
var playBack = PlaybackManager.Inst.AudioOutput;
var playbackState = playBack.PlaybackState;
if (viewModel.Singer != null) {
var sample = viewModel.Singer.Sample;
if (sample != null && File.Exists(sample)) {
var playSample = Wave.OpenFile(sample);
playBack.Init(playSample.ToSampleProvider());
playBack.Play();
if (playbackState == PlaybackState.Playing) {
playBack.Stop();
}
} else {
var path = viewModel.Singer.Location;
string[] files = Directory.EnumerateFiles(path, "*.wav", SearchOption.AllDirectories)
.Union(Directory.EnumerateFiles(path, "*.mp3", SearchOption.AllDirectories))
.Union(Directory.EnumerateFiles(path, "*.flac", SearchOption.AllDirectories))
.Union(Directory.EnumerateFiles(path, "*.aiff", SearchOption.AllDirectories))
.Union(Directory.EnumerateFiles(path, "*.ogg", SearchOption.AllDirectories))
.Union(Directory.EnumerateFiles(path, "*.opus", SearchOption.AllDirectories))
.ToArray();
Random rnd = new Random(Guid.NewGuid().GetHashCode());
int choice = rnd.Next(0, files.Length - 1);
string soundFile = files[choice];
var playSound = Wave.OpenFile(soundFile);
playBack.Init(playSound.ToSampleProvider());
playBack.Play();
if (playbackState == PlaybackState.Playing) {
playBack.Stop();
}
}
}
}

void RegenFrq(object sender, RoutedEventArgs args) {
if (OtoGrid != null &&
sender is Control control &&
Expand Down

0 comments on commit 43d5431

Please sign in to comment.