Skip to content

Commit

Permalink
Version 2.9.0 (#75)
Browse files Browse the repository at this point in the history
* Bump Avalonia version

* Bump Avalonia to version 11.0.10

* Add Keyboard hook logic to support Linux and MacOS hotkeys (#68)

* Add SharpHook dependency and new keyboard hook logic to support Linux and MacOS

* Improve performance and fix key unbinding

* Update readme with hotkey information

* Update website with hotkey information

* feat(73): Add option to start/stop SoundClips rather than playing multiple instances (#74)

* feat(73): Add option to start/stop SoundClips rather than playing multiple instances

* Cleanup
  • Loading branch information
dan0v authored Apr 10, 2024
1 parent fa82891 commit 74675e8
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 35 deletions.
4 changes: 2 additions & 2 deletions AmplitudeSoundboard.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<RootNamespace>Amplitude</RootNamespace>
<NeutralLanguage>en</NeutralLanguage>
<Platforms>AnyCPU;x64</Platforms>
<Version>2.8.0</Version>
<Version>2.9.0</Version>
<CopyOutputSymbolsToPublishDirectory>false</CopyOutputSymbolsToPublishDirectory>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
Expand All @@ -42,7 +42,7 @@
<PackageReference Include="ManagedBass.Flac" Version="3.1.1" />
<PackageReference Include="ManagedBass.Mix" Version="3.1.1" />
<PackageReference Include="ManagedBass.Opus" Version="3.1.1" />
<PackageReference Include="SharpHook" Version="5.3.1" />
<PackageReference Include="SharpHook" Version="5.3.2" />
</ItemGroup>
<ItemGroup>
<Compile Update="Localization\Language.Designer.cs">
Expand Down
71 changes: 59 additions & 12 deletions Helpers/MSoundEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public List<string> OutputDeviceListWithGlobal
{
get
{
List<string> devices = new List<string>();
List<string> devices = [];
// Index 0 is "No Sound", so skip
for (int dev = 1; dev < Bass.DeviceCount; dev++)
{
Expand Down Expand Up @@ -157,20 +157,67 @@ public void AddToQueue(SoundClip source)
}
}

private void StopAndRemoveFromQueue(string id)
{
lock (queueLock)
{
var toRemove = Queued.Where(clip => clip.Id == id).ToList();
foreach (var clip in toRemove)
{
Queued.Remove(clip);
}
}
lock (currentlyPlayingLock)
{
var toRemove = CurrentlyPlaying.Where(clip => clip.SoundClipId == id).ToList();
foreach (var clip in toRemove)
{
Bass.StreamFree(clip.BassStreamId);
CurrentlyPlaying.Remove(clip);
}
}
}

private bool ClipPlayingOrQueued(string id)
{
lock (queueLock)
{
if (Queued.Any(clip => clip.Id == id))
{
return true;
}
}
lock (currentlyPlayingLock)
{
if (CurrentlyPlaying.Any(clip => clip.SoundClipId == id))
{
return true;
}
}
return false;
}

public void Play(SoundClip source)
{
var tempId = source.Id ?? source.AudioFilePath;
if (App.ConfigManager.Config.StopAudioOnRepeatTrigger && ClipPlayingOrQueued(tempId))
{
StopAndRemoveFromQueue(tempId);
return;
}

if (!BrowseIO.ValidAudioFile(source.AudioFilePath, true, source))
{
return;
}

foreach (OutputSettings settings in source.OutputSettingsFromProfile)
{
Play(source.AudioFilePath, settings.Volume, source.Volume, settings.DeviceName, source.LoopClip, source.Name);
Play(source.AudioFilePath, settings.Volume, source.Volume, settings.DeviceName, source.LoopClip, tempId, source.Name);
}
}

private void Play(string fileName, int volume, int volumeMultiplier, string playerDeviceName, bool loopClip, string? name = null)
private void Play(string fileName, int volume, int volumeMultiplier, string playerDeviceName, bool loopClip, string soundClipId, string ? name = null)
{
double vol = (volume / 100.0) * (volumeMultiplier / 100.0);

Expand Down Expand Up @@ -205,7 +252,7 @@ private void Play(string fileName, int volume, int volumeMultiplier, string play
{
var len = Bass.ChannelGetLength(stream, PositionFlags.Bytes);
double length = Bass.ChannelBytes2Seconds(stream, len);
PlayingClip track = new PlayingClip(name ?? Path.GetFileNameWithoutExtension(fileName) ?? "", playerDeviceName, stream, length, loopClip);
PlayingClip track = new (string.IsNullOrEmpty(name) ? Path.GetFileNameWithoutExtension(fileName) ?? "" : name, soundClipId, playerDeviceName, stream, length, loopClip);

lock(currentlyPlayingLock)
{
Expand Down Expand Up @@ -269,14 +316,6 @@ public void Reset()
}
}

public void Dispose()
{
timer.Stop();
timer.Elapsed -= RefreshPlaybackProgressAndCheckQueue;
Reset();
Bass.Free();
}

public void StopPlaying(int bassId)
{
lock (currentlyPlayingLock)
Expand All @@ -297,5 +336,13 @@ public void RemoveFromQueue(SoundClip clip)
Queued.Remove(clip);
}
}

public void Dispose()
{
timer.Stop();
timer.Elapsed -= RefreshPlaybackProgressAndCheckQueue;
Reset();
Bass.Free();
}
}
}
9 changes: 9 additions & 0 deletions Localization/Language.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Localization/Language.es.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Buscar actualizaciones</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Alternar audio cuando se activa repetidamente</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Localization/Language.hu.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Frissítések keresése</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Hang ki/bekapcsolása többszörös indítás esetén</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Localization/Language.it.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Controlla gli aggiornamenti</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Attiva/disattiva l'audio quando viene attivato ripetutamente</value>
</data>
</root>
5 changes: 4 additions & 1 deletion Localization/Language.nl.resx
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@
<value>Het uitvoerprofiel "{0}" ontbreekt en kan niet worden gebruikt om af te spelen!</value>
</data>
<data name="OutputProfileError" xml:space="preserve">
<value>Het uitvoerprofiel "{0}" heeft fouten:\\n{1}</value>.
<value>.</value>
</data>
<data name="EditOutputProfileTitle" xml:space="preserve">
<value>Bewerk uitvoerprofiel</value>
Expand All @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Controleer op updates</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Schakel audio in wanneer herhaaldelijk geactiveerd</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Localization/Language.pl.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Sprawdź aktualizacje</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Przełącz dźwięk po wielokrotnym uruchomieniu</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Localization/Language.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Check for updates</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Toggle audio when triggered repeatedly</value>
</data>
</root>
3 changes: 3 additions & 0 deletions Localization/Language.ru.resx
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,7 @@
<data name="CheckForUpdates" xml:space="preserve">
<value>Проверьте наличие обновлений</value>
</data>
<data name="StopAudioOnRetrigger" xml:space="preserve">
<value>Переключение звука при неоднократном срабатывании</value>
</data>
</root>
14 changes: 14 additions & 0 deletions Models/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ public bool HideTutorial
}
}

private bool _stopAudioOnRepeatTrigger = false;
public bool StopAudioOnRepeatTrigger
{
get => _stopAudioOnRepeatTrigger;
set
{
if (value != _stopAudioOnRepeatTrigger)
{
_stopAudioOnRepeatTrigger = value;
OnPropertyChanged();
}
}
}

public Config()
{
Language = Localizer.Instance.TryUseSystemLanguageFallbackEnglish();
Expand Down
4 changes: 3 additions & 1 deletion Models/PlayingClip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace Amplitude.Models
public class PlayingClip : INotifyPropertyChanged
{
public string Name { get; init; }
public string SoundClipId { get; init; }
public string OutputDevice { get; init; }
public double Length { get; init; }
public int BassStreamId { get; init; }
Expand Down Expand Up @@ -67,13 +68,14 @@ public void StopPlayback()
App.SoundEngine.StopPlaying(BassStreamId);
}

public PlayingClip(string name, string outputDevice, int bassStreamId, double length, bool loopClip)
public PlayingClip(string name, string soundClipId, string outputDevice, int bassStreamId, double length, bool loopClip)
{
if (length == 0)
{
throw new ArgumentOutOfRangeException();
}
Name = name;
SoundClipId = soundClipId;
OutputDevice = outputDevice;
BassStreamId = bassStreamId;
Length = length;
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,24 @@

## Installation
### Windows *(x64)*
1. Download and unzip [latest Windows build](https://git.dan0v.com/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_win_x86_64.zip) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/)
2. Run executable (`amplitude_soundboard.exe`)
3. If you would like to play sound through an input device like a microphone, set up a program like [Virtual Audio Cable](https://vac.muzychenko.net/en/download.htm) and set the newly created virtual cable as your clip output device
1. Download and unzip [latest Windows build](https://git.dan0v.com/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_win_x86_64.zip) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/).
2. Run executable (`amplitude_soundboard.exe`).
3. If you would like to play sound through an input device like a microphone, set up a program like [Virtual Audio Cable](https://vac.muzychenko.net/en/download.htm) and set the newly created virtual cable as your clip output device.

### MacOS *(x64)*
1. Download and unzip [latest MacOS build](https://github.com/dan0v/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_macOS_x86_64.tar.gz) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/)
2. Run executable (`Amplitude Soundboard.app`)
- If a security warning blocks the app from running, open `System Preferences -> Security & Privacy -> General` and click `Open Anyway`. This is due to not signing the app with an Apple Developer ID
3. If you would like to play sound through an input device like a microphone, set up a program like [BlackHole](https://github.com/ExistentialAudio/BlackHole) and set the newly created virtual cable as your clip output device
1. Download and unzip [latest MacOS build](https://github.com/dan0v/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_macOS_x86_64.tar.gz) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/).
2. Run executable (`Amplitude Soundboard.app`).
- If a security warning blocks the app from running, open `System Preferences -> Privacy & Security -> General` and click `Open Anyway`. This is due to not signing the app with an Apple Developer ID.
- In order to use hotkeys, Amplitude Soundboard must be given accessibility permission to control your computer. This can be done under `System Preferences -> Privacy & Security -> Accessibility`. A popup should take you directly to this option at application startup. Amplitude Soundboard will need to be restarted after granting permissions for hotkeys to start working.
3. If you would like to play sound through an input device like a microphone, set up a program like [BlackHole](https://github.com/ExistentialAudio/BlackHole) and set the newly created virtual cable as your clip output device.

### Linux *(x64)*
1. Download and unzip [latest Linux build](https://github.com/dan0v/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_linux_AppImage_x86_64.tar.gz) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/)
2. Run executable (`Amplitude_Soundboard-x86_64.AppImage`)
3. If you would like to play sound through an input device like a microphone, [set up a sink in PulseAudio](https://www.onetransistor.eu/2017/10/virtual-audio-cable-in-linux-ubuntu.html) and set the monitor output of it to your desired input device
1. Download and unzip [latest Linux build](https://github.com/dan0v/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_linux_AppImage_x86_64.tar.gz) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/).
2. Run executable (`Amplitude_Soundboard-x86_64.AppImage`).
- Hotkeys will currently only work under x11, not Wayland, as supported by [SharpHook](https://github.com/TolikPylypchuk/SharpHook).
3. If you would like to play sound through an input device like a microphone, [set up a sink in PulseAudio](https://www.onetransistor.eu/2017/10/virtual-audio-cable-in-linux-ubuntu.html) and set the monitor output of it to your desired input device.

## Updating
## Updates
### Windows
A dialog automatically notifies users of available updates at application startup. To automatically update, click `Update`, or, to manually update, just download the [latest Windows build](https://git.dan0v.com/AmplitudeSoundboard/releases/latest/download/Amplitude_Soundboard_win_x86_64.zip) from the [Releases page](https://git.dan0v.com/AmplitudeSoundboard/releases/) and replace your `amplitude_soundboard.exe` with the new version.

Expand Down Expand Up @@ -88,7 +90,6 @@ Many thanks to all these people! ([emoji key](https://allcontributors.org/docs/e
<td align="center" valign="top" width="14.28%"><a href="https://ktos.info"><img src="https://avatars.githubusercontent.com/u/1633261?v=4?s=100" width="100px;" alt="Marcin Badurowicz"/><br /><sub><b>Marcin Badurowicz</b></sub></a><br /><a href="#translation-ktos" title="Translation">🌍</a> <a href="https://github.com/dan0v/AmplitudeSoundboard/commits?author=ktos" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Swell61"><img src="https://avatars.githubusercontent.com/u/32226560?v=4?s=100" width="100px;" alt="Samuel"/><br /><sub><b>Samuel</b></sub></a><br /><a href="#userTesting-swell61" title="User Testing">📓</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/teacup775"><img src="https://avatars.githubusercontent.com/u/2474259?v=4?s=100" width="100px;" alt="teacup775"/><br /><sub><b>teacup775</b></sub></a><br /><a href="#userTesting-teacup775" title="User Testing">📓</a></td>
</tr>
</tbody>
</table>
Expand Down
20 changes: 15 additions & 5 deletions Views/GlobalSettings.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
xmlns:vm="using:Amplitude.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="680"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="730"
xmlns:i18n="clr-namespace:Amplitude.Localization"
xmlns:converters="clr-namespace:Amplitude.Converters"
x:Class="Amplitude.Views.GlobalSettings"
Icon="/Assets/Icon.ico"
Title="{i18n:Localize GlobalSettingsTitle}"
Width="400" Height="680" MinWidth="400" MinHeight="320"
Width="400" Height="730" MinWidth="400" MinHeight="320"
TransparencyLevelHint="AcrylicBlur"
Background="Transparent"
ExtendClientAreaToDecorationsHint="{Binding CanUseCustomTitlebar}">
Expand Down Expand Up @@ -140,13 +140,16 @@
</StackPanel>
</Grid>
</Border>
<!--Clear position data-->

<!--Stop audio when retriggered-->
<Border BorderThickness="2" CornerRadius="5" Margin="5" Padding="5">
<Border.BorderBrush>
<SolidColorBrush Color="{Binding ThemeHandler.BorderColor}"/>
</Border.BorderBrush>
<Button HorizontalAlignment="Center" Margin="5,0,5,0" VerticalAlignment="Center" Command="{Binding ClearPositions}" Content="{i18n:Localize ClearPositions}" ToolTip.Tip="{i18n:Localize ClearPositionsTooltip}" Cursor="Hand"/>
<Grid ColumnDefinitions="*,Auto" HorizontalAlignment="Center">
<TextBlock Grid.Column="0" VerticalAlignment="Center" Margin="5,0,5,0" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Text="{i18n:Localize StopAudioOnRetrigger}" ></TextBlock>
<CheckBox Grid.Column="1" HorizontalAlignment="Center" Margin="5,0,5,0" VerticalAlignment="Center" IsChecked="{Binding Model.StopAudioOnRepeatTrigger}" Cursor="Hand"/>
</Grid>
</Border>

<!--Check for updates-->
Expand All @@ -171,6 +174,13 @@
</Grid>
</Border>

<!--Clear position data-->
<Border BorderThickness="2" CornerRadius="5" Margin="5" Padding="5">
<Border.BorderBrush>
<SolidColorBrush Color="{Binding ThemeHandler.BorderColor}"/>
</Border.BorderBrush>
<Button HorizontalAlignment="Center" Margin="5,0,5,0" VerticalAlignment="Center" Command="{Binding ClearPositions}" Content="{i18n:Localize ClearPositions}" ToolTip.Tip="{i18n:Localize ClearPositionsTooltip}" Cursor="Hand"/>
</Border>

<!--Save button-->
<Grid ColumnDefinitions="*,Auto">
Expand Down
2 changes: 1 addition & 1 deletion Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="*,Auto" >
<TextBlock Grid.Row="0" Text="{Binding Name}" ToolTip.Tip="{Binding Name}" TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis" VerticalAlignment="Center" HorizontalAlignment="Center" />
<TextBlock Grid.Column="0" Text="{Binding Name}" ToolTip.Tip="{Binding Name}" TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis" VerticalAlignment="Center" HorizontalAlignment="Center" />
<Button Grid.Column="1" ToolTip.Tip="{i18n:Localize Remove}" Command="{Binding $parent[ItemsControl].DataContext.RemoveFromQueue}" CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Mode=Self}}" Cursor="Hand" Margin="2">
<Panel>
<Image Source="{Binding $parent[ItemsControl].DataContext.ThemeHandler.RemoveItem}" Height="15" VerticalAlignment="Center" HorizontalAlignment="Center" />
Expand Down
Loading

0 comments on commit 74675e8

Please sign in to comment.