Skip to content

Commit

Permalink
Next WiimoteAudioPlayer Release 1.0.1
Browse files Browse the repository at this point in the history
* Improved PCM playback (still playable, but you can not barely make out the faintest sign of intelligible audio)
* More use of following Wiibrew Wiimote documentation.
* A TON of helpful tooltips in the audio player, to explain what should be known.
* Support for PCM playback in the audio player.
* Fixed Bolded text for volume and sample rate spinners being incorrectly switched.
* Fixed missing required wave conversion during change in Audio sample rate.
* Wiimote Audio Player no longer requires WiimoteController.exe to function as a library.
* More changes to pairing system. Added Bluetooth PairOnDiscovered option. AutoConnect is now enabled by default like before.
  • Loading branch information
trigger-segfault committed Jan 14, 2020
1 parent 79f6b6b commit 93b521b
Show file tree
Hide file tree
Showing 62 changed files with 752 additions and 101 deletions.
4 changes: 2 additions & 2 deletions ReportInspector/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public MainWindow() {
Close();
return;*/

//FIXME: AutoConnect/Unpair is broken on Windows 10, it'll cause
//FIXME: UnpairOnDisconnect is broken on Windows 10, it'll cause
// more problems than solve them at this point in time.
WiimoteManager.AutoConnect = false;// true;
WiimoteManager.AutoConnect = true;
WiimoteManager.AutoDiscoveryCount = 1;
WiimoteManager.DolphinBarMode = true;
WiimoteManager.BluetoothMode = true;
Expand Down
6 changes: 3 additions & 3 deletions ReportInspector/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ReportInspector")]
[assembly: AssemblyTitle("Wiimote Report Inspector")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany("Trigger's Tools & Games")]
[assembly: AssemblyProduct("ReportInspector")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyCopyright("Copyright © Robert Jordan 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand Down
43 changes: 34 additions & 9 deletions WiimoteAudioPlayer/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WiimoteAudioPlayer"
xmlns:local2="clr-namespace:WiimoteController.Controls;assembly=WiimoteController"
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
mc:Ignorable="d"
Title="Wiimote Audio Player" Height="430" Width="500" Background="#FFF0F0F0" Icon="App.ico" UseLayoutRounding="True" SnapsToDevicePixels="True" ResizeMode="NoResize" AllowDrop="True" DragEnter="OnDragEnter" DragLeave="OnDragLeave" DragOver="OnDragOver" Drop="OnDrop" Loaded="OnLoaded" Closed="OnClosed">
<!--
xmlns:local2="clr-namespace:WiimoteController.Controls;assembly=WiimoteController"
-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0"/>
Expand All @@ -25,14 +27,13 @@
</Grid.ColumnDefinitions>
<local:WaveformDisplay x:Name="waveform" Margin="5" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<Border BorderThickness="1" BorderBrush="DarkGray" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="Auto" Margin="5" Grid.Column="1">
<local2:WiimoteDisplay x:Name="wmDisplay" Height="230" Width="Auto" />
<local:WiimoteDisplay x:Name="wmDisplay" Height="230" Width="Auto" />
</Border>
<Border x:Name="borderBattery" BorderBrush="DarkGray" Margin="5" Grid.Column="1" VerticalAlignment="Bottom" Height="20" BorderThickness="1" Background="#FF3C3C3C">
<Rectangle x:Name="rectBattery" Fill="LimeGreen" HorizontalAlignment="Left" />
</Border>
<StackPanel VerticalAlignment="Bottom" Margin="5,0,0,5">
<Label x:Name="labelFile" Content="File:" FontWeight="Regular" Margin="0,5,0,0"/>
<CheckBox x:Name="checkBoxMaximize" Content="Maximize Volume" Padding="4,-1,0,0" Margin="4,2,0,0" IsChecked="True" Click="OnMaximizeVolumeChanged" />
<Grid VerticalAlignment="Bottom" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
Expand All @@ -41,16 +42,40 @@
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="labelSampleRate" Content="Sample Rate:" Grid.Column="0" Grid.Row="2" FontWeight="Regular" Padding="5,4"/>
<xctk:IntegerUpDown x:Name="spinnerSampleRate" Grid.Column="1" Grid.Row="2" Value="3000" Maximum="5000" Minimum="1000" Height="24" ValueChanged="OnSampleRateChanged" DefaultValue="3000" Increment="500" ToolTip="Recommended: ADPCM 3000Hz | PCM 1500Hz"/>
<Label x:Name="labelVolume" Content="Volume:" Grid.Column="3" Grid.Row="2" FontWeight="Regular" Padding="5,4"/>
<xctk:SingleUpDown x:Name="spinnerVolume" Grid.Column="4" Grid.Row="2" Value="1" Maximum="1" Minimum="0.01" Height="24" ValueChanged="OnVolumeChanged" Increment="0.05" DefaultValue="1" DisplayDefaultValueOnEmptyText="True" FormatString="0.000" ToolTip="Recommended: ADPCM 1.0 | PCM 0.2-0.4"/>
<CheckBox x:Name="checkBoxADPCM" Content="ADPCM" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Padding="4,-1,0,0" Margin="4,2,0,0" IsChecked="True" Click="OnADPCMChanged" HorizontalAlignment="Left" ToolTip="Checked: ADPCM format | Unchecked: PCM format" />
<CheckBox x:Name="checkBoxMaximize" Content="Maximize Volume" Grid.Column="3" Grid.ColumnSpan="2" Grid.Row="0" Padding="4,-1,0,0" Margin="4,2,0,0" IsChecked="True" Click="OnMaximizeVolumeChanged" HorizontalAlignment="Left" ToolTip="Recommended: ADPCM on | PCM off" />
</Grid>
<!-- <CheckBox x:Name="checkBoxMaximize" Content="Maximize Volume" Grid.Column="4" Padding="4,-1,0,0" Margin="4,2,0,0" IsChecked="True" Click="OnMaximizeVolumeChanged" />
<Grid VerticalAlignment="Bottom" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="labelSampleRate" Content="Sample Rate:" FontWeight="Regular" Grid.Column="0" Padding="5,4"/>
<xctk:IntegerUpDown x:Name="spinnerSampleRate" Value="3000" Maximum="5000" Minimum="1000" Height="24" Grid.Column="1" ValueChanged="OnSampleRateChanged" DefaultValue="3000" Increment="500"/>
<Label x:Name="labelVolume" Content="Volume:" FontWeight="Regular" Grid.Column="3" Padding="5,4"/>
<xctk:SingleUpDown x:Name="spinnerVolume" Value="1" Maximum="1" Minimum="0.01" Height="24" Grid.Column="4" ValueChanged="OnVolumeChanged" Increment="0.05" DefaultValue="1" DisplayDefaultValueOnEmptyText="True" FormatString="0.000"/>
</Grid>
<Button x:Name="buttonUpdateSampleRate" Content="Update Changes" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnUpdateSettings" IsEnabled="False" IsTabStop="False" Focusable="False"/>
<Button x:Name="buttonPlayWave" Content="Play on Computer" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnPlayReal" IsEnabled="False" IsTabStop="False" Focusable="False"/>
<Button x:Name="buttonPlayWiimote" Content="Play on Wiimote" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnPlayWiimote" IsEnabled="False" IsTabStop="False" Focusable="False"/>
<Button x:Name="buttonStop" Content="Stop Playback" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnStop" IsEnabled="False" IsTabStop="False" Focusable="False"/>
<Button x:Name="buttonLoadSound" Content="Load Sound" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnLoadSound" IsEnabled="True" IsTabStop="False" Focusable="False"/>
</Grid>-->
<Button x:Name="buttonUpdateSampleRate" Content="Update Changes" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnUpdateSettings" IsEnabled="False" IsTabStop="False" Focusable="False" ToolTip="Controls above with bold text require updating"/>
<Button x:Name="buttonPlayWave" Content="Play on Computer" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnPlayReal" IsEnabled="False" IsTabStop="False" Focusable="False" ToolTip="Play converted audio through computer speakers (as PCM)"/>
<Button x:Name="buttonPlayWiimote" Content="Play on Wiimote" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnPlayWiimote" IsEnabled="False" IsTabStop="False" Focusable="False" ToolTip="Play converted audio through Wiimote speaker"/>
<Button x:Name="buttonStop" Content="Stop Playback" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnStop" IsEnabled="False" IsTabStop="False" Focusable="False" ToolTip="Stop audio playback on Wiimote or computer"/>
<Button x:Name="buttonLoadSound" Content="Load Sound" VerticalAlignment="Bottom" FontWeight="Bold" Height="28" Margin="0,5,0,0" Click="OnLoadSound" IsEnabled="True" IsTabStop="False" Focusable="False" ToolTip="You may also drag a sound file into the window"/>
</StackPanel>
</Grid>
<Label x:Name="labelDrop" Content="Drop Sound Files Here" Grid.ColumnSpan="2" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="#88FFFFFF" Opacity="0.8" FontSize="22" FontWeight="Bold" Visibility="Collapsed"/>
Expand Down
150 changes: 114 additions & 36 deletions WiimoteAudioPlayer/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ public MainWindow() {
private int sampleRate = 3000;
private float volume = 1f;
private bool maximize = true;
private int convertedSampleRate = 0;

private SpeakerFormat speakerFormat = SpeakerFormat.PCM;
private string waveFile;
private string convertedWaveFile;
private string finalWaveFile;
private byte[] adpcm;
private object soundObj;
//private byte[] soundData;
//private PrebufferedSound prebufferedSound;

private void OnLoadSound(object sender, RoutedEventArgs e) {
OpenFileDialog dialog = new OpenFileDialog {
Expand All @@ -50,17 +54,18 @@ private void OnLoadSound(object sender, RoutedEventArgs e) {
}

private void LoadSound(string newWaveFile) {
player.Close();
/*player.Close();
Wiimote?.StopSound();
waveform.Stop();
Thread.Sleep(300);
Thread.Sleep(300);*/

int newSampleRate = sampleRate;
string newConvertedWaveFile;
ADPCMConverter.ConvertToValidWav(newWaveFile, out newConvertedWaveFile, ref newSampleRate);
if (UpdateWaveFile(newConvertedWaveFile, newSampleRate, volume, maximize, true)) {
waveFile = newWaveFile;
labelFile.Content = "File: " + Path.GetFileName(waveFile);
//int newSampleRate = sampleRate;
//string newConvertedWaveFile;
//ADPCMConverter.ConvertToValidWav(newWaveFile, out newConvertedWaveFile, ref newSampleRate);
//if (PrepareWaveFile(newConvertedWaveFile, newSampleRate, volume, maximize, true)) {
if (PrepareWaveFile(newWaveFile, sampleRate, volume, maximize, speakerFormat, true)) {
//waveFile = newWaveFile;
labelFile.Content = "File: " + Path.GetFileName(newWaveFile);
buttonPlayWave.IsEnabled = true;
buttonPlayWiimote.IsEnabled = WiimoteManager.ConnectedWiimotes.Any();
buttonStop.IsEnabled = true;
Expand All @@ -77,13 +82,23 @@ private void OnPlayReal(object sender, RoutedEventArgs e) {

private void OnPlayWiimote(object sender, RoutedEventArgs e) {
player.Stop();
Wiimote?.EnableSpeaker(new SpeakerConfiguration {
SpeakerConfiguration config = new SpeakerConfiguration {
Volume = volume,
//Unknown2 = 0x0c,
//Unknown3 = 0x0e,
SampleRate = sampleRate,
});
Wiimote?.PlaySound(adpcm);
Format = speakerFormat,
};
Wiimote?.DisableSpeaker();
Wiimote?.EnableSpeaker(config);
Thread.Sleep(100);
Wiimote?.DisableSpeaker();
Wiimote?.EnableSpeaker(config);
//byte[] configData = Wiimote.ReadData(0x04a20001, 7);
//if (soundObj is PrebufferedSound prebuffered)
// Wiimote?.PlaySound(prebuffered);
//else
Wiimote?.PlaySound((byte[]) soundObj);
waveform.Play();
}

Expand All @@ -96,7 +111,7 @@ private void UpdateBattery() {
}

private void OnSampleRateChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
if (IsLoaded && adpcm != null) {
if (IsLoaded && soundObj != null) {
labelSampleRate.FontWeight = SampleRateFontWeight;
}
}
Expand Down Expand Up @@ -137,20 +152,31 @@ private void OnDrop(object sender, DragEventArgs e) {
}

private void OnLoaded(object sender, RoutedEventArgs e) {
//FIXME: AutoConnect/Unpair is broken on Windows 10, it'll cause
speakerFormat = SpeakerFormat.ADPCM;
maximize = true;
checkBoxMaximize.IsChecked = maximize;
if (speakerFormat == SpeakerFormat.ADPCM)
sampleRate = 3000;
else
sampleRate = 2000;
spinnerSampleRate.Value = sampleRate;
CheckBoxSpeakerFormat = speakerFormat;
//FIXME: UnpairOnDisconnect is broken on Windows 10, it'll cause
// more problems than solve them at this point in time.
WiimoteManager.AutoConnect = false;// true;
WiimoteManager.UnpairOnDisconnect = false;// true;
WiimoteManager.PairOnDiscover = false;// true;
WiimoteManager.AutoConnect = true;
WiimoteManager.AutoDiscoveryCount = 1;
WiimoteManager.DolphinBarMode = true;
WiimoteManager.BluetoothMode = true;
WiimoteManager.AutoDiscoveryCount = 1;
WiimoteManager.Connected += OnWiimoteConnected;
WiimoteManager.Disconnected += OnWiimoteDisconnected;
UpdateBattery();
}

private void OnWiimoteConnected(object sender, WiimoteEventArgs e) {
Dispatcher.Invoke(() => {
buttonPlayWiimote.IsEnabled = adpcm != null;
buttonPlayWiimote.IsEnabled = soundObj != null;
UpdateBattery();
});
}
Expand Down Expand Up @@ -179,61 +205,113 @@ private void OnUpdateSettings(object sender, RoutedEventArgs e) {
int newSampleRate = spinnerSampleRate.Value ?? sampleRate;
float newVolume = spinnerVolume.Value ?? volume;
bool newMaximize = checkBoxMaximize.IsChecked ?? maximize;
UpdateWaveFile(newSampleRate, newVolume, newMaximize);
SpeakerFormat newSpeakerFormat = CheckBoxSpeakerFormat;
UpdateWaveFile(newSampleRate, newVolume, newMaximize, newSpeakerFormat);
}

private void OnVolumeChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
if (IsLoaded && adpcm != null) {
if (IsLoaded && soundObj != null) {
labelVolume.FontWeight = VolumeFontWeight;
}
}

private void OnMaximizeVolumeChanged(object sender, RoutedEventArgs e) {
if (IsLoaded && adpcm != null) {
if (IsLoaded && soundObj != null) {
checkBoxMaximize.FontWeight = MaximizeFontWeight;
}
}

private FontWeight VolumeFontWeight {
get => ((spinnerSampleRate.Value ?? 0) == sampleRate ? FontWeights.Bold : FontWeights.Regular);
private void OnADPCMChanged(object sender, RoutedEventArgs e) {
if (IsLoaded && soundObj != null) {
checkBoxADPCM.FontWeight = ADPCMFontWeight;
}
}
private SpeakerFormat CheckBoxSpeakerFormat {
get => ((checkBoxADPCM.IsChecked??true) ? SpeakerFormat.ADPCM : SpeakerFormat.PCM);
set => checkBoxADPCM.IsChecked = (value == SpeakerFormat.ADPCM);
}

private FontWeight SampleRateFontWeight {
get => ((spinnerVolume.Value ?? 0f) == volume ? FontWeights.Bold : FontWeights.Regular);
get => ((spinnerSampleRate.Value ?? 0) != sampleRate ? FontWeights.Bold : FontWeights.Regular);
}

private FontWeight VolumeFontWeight {
get => ((spinnerVolume.Value ?? 0f) != volume ? FontWeights.Bold : FontWeights.Regular);
}

private FontWeight MaximizeFontWeight {
get => ((checkBoxMaximize.IsChecked ?? true) == maximize ? FontWeights.Bold : FontWeights.Regular);
get => ((checkBoxMaximize.IsChecked ?? true) != maximize ? FontWeights.Bold : FontWeights.Regular);
}

private bool UpdateWaveFile(int newSampleRate, float newVolume, bool newMaximize) {
return UpdateWaveFile(convertedWaveFile, newSampleRate, newVolume, newMaximize);
private FontWeight ADPCMFontWeight {
get => (CheckBoxSpeakerFormat != speakerFormat ? FontWeights.Bold : FontWeights.Regular);
}

private bool UpdateWaveFile(string newConvertedWaveFile, int newSampleRate, float newVolume, bool newMaximize, bool alreadyStopped = false) {
try {
if (!alreadyStopped) {
player.Close();
Wiimote?.StopSound();
waveform.Stop();
Thread.Sleep(300);
}
private bool ConvertWaveFile(string newWaveFile, out string newConvertedWaveFile, bool forceConvert, int newSampleRate) {
if (forceConvert || newWaveFile != waveFile || newSampleRate != convertedSampleRate) {
ADPCMConverter.ConvertToValidWav(newWaveFile, out newConvertedWaveFile, ref newSampleRate);
waveFile = newWaveFile;
convertedWaveFile = newConvertedWaveFile;
convertedSampleRate = newSampleRate;
//labelFile.Content = "File: " + Path.GetFileName(waveFile);
//buttonPlayWave.IsEnabled = true;
//buttonPlayWiimote.IsEnabled = WiimoteManager.ConnectedWiimotes.Any();
//buttonStop.IsEnabled = true;
//buttonUpdateSampleRate.IsEnabled = true;
return true;
}
convertedWaveFile = waveFile;
newConvertedWaveFile = waveFile;
return false;
}

private bool UpdateWaveFile(int newSampleRate, float newVolume, bool newMaximize, SpeakerFormat newSpeakerFormat) {
return PrepareWaveFile(waveFile, newSampleRate, newVolume, newMaximize, newSpeakerFormat, false);
}

//private bool UpdateWaveFile(string newConvertedWaveFile, int newSampleRate, float newVolume, bool newMaximize, bool shouldStop = false) {
private bool PrepareWaveFile(string newWaveFile, int newSampleRate, float newVolume, bool newMaximize, SpeakerFormat newSpeakerFormat, bool forceConvert = true, bool stop = true) {
if (stop) {
player.Close();
Wiimote?.StopSound();
waveform.Stop();
Thread.Sleep(300);
}

try {
string newConvertedWaveFile;
ConvertWaveFile(newWaveFile, out newConvertedWaveFile, /*forceConvert*/true, newSampleRate);
string newFinalWaveFile = newConvertedWaveFile;
if (newMaximize)
ADPCMConverter.MaximizeWavVolume(newConvertedWaveFile, out newFinalWaveFile);
byte[] data = ADPCMConverter.Wav2ADPCMData(newFinalWaveFile, out newSampleRate);
object newSoundObj = null;
byte[] data = null;
if (newSpeakerFormat == SpeakerFormat.ADPCM) {
//newSoundObj = WiiRemoteJAudioConverter.bufferADPCMSound(newFinalWaveFile);
data = ADPCMConverter.Wav2ADPCMData(newFinalWaveFile, out newSampleRate);
}
else {
data = ADPCMConverter.Wav2PCMs8Data(newFinalWaveFile, out newSampleRate);
//throw new NotSupportedException("8-bit signed PCM not supported yet!");
//newSoundObj = WiiRemoteJAudioConverter.bufferPCMs8Sound(newFinalWaveFile);
//data = ADPCMConverter.Wav2PCMs8Data(newFinalWaveFile, out newSampleRate);
//TODO: We probably dont need to previous step, it'll make things more complicated
}
player.Open(new Uri(newFinalWaveFile));
waveform.InitWave(newFinalWaveFile);
adpcm = data;
soundObj = newSoundObj ?? data;
//soundObj = newSoundObj;
//soundData = data;
convertedWaveFile = newConvertedWaveFile;
finalWaveFile = newFinalWaveFile;
sampleRate = newSampleRate;
volume = newVolume;
maximize = newMaximize;
speakerFormat = newSpeakerFormat;
labelSampleRate.FontWeight = SampleRateFontWeight;
labelVolume.FontWeight = VolumeFontWeight;
checkBoxMaximize.FontWeight = MaximizeFontWeight;
checkBoxADPCM.FontWeight = ADPCMFontWeight;
return true;
}
catch (Exception ex) {
Expand Down
Loading

0 comments on commit 93b521b

Please sign in to comment.