diff --git a/config.sample.toml b/config.sample.toml index 7052607..e8c9a38 100644 --- a/config.sample.toml +++ b/config.sample.toml @@ -22,24 +22,29 @@ incoming_endpoint = "127.0.0.1:9001" use_decibels = false # The amount that the volume should be increased when using the volume keys. -# Percentage: Up to max of 0.10 which will increase the volume by 10%. -increment = 0.02 -# Decibels: Up to max of 6.0 dB in multiples of 0.25 (e.g. 0.25, 0.5, 0.75, etc.). -# increment = 2.0 +# Up to max of 0.10 which will increase the volume by 10%. +increment_percent = 0.02 # The amount that the volume should be increased when using the volume keys and holding shift down. -# Percentage: Up to a max of 0.05 which will increase the volume by 5%. -fine_increment = 0.01 -# Decibels: Up to max of 3.0 dB in multiples of 0.25 (i.e.. 0.25, 0.5, 0.75, etc.). When using -# decibels, it is generally a good idea to ensure the fine increment is a multiple of -# increment. -# fine_increment = 0.5 +# Up to a max of 0.05 which will increase the volume by 5%. +fine_increment_percent = 0.01 # The maximum volume to send. -# Percentage: Up to a max of 1.0 which is 100% volume. -max = 1.0 -# Decibels: Up to max of 6.0 dB. -# max = 6.0 +# Up to a max of 1.0 which is 100% volume. +max_percent = 1.0 + +# The amount that the volume should be increased when using the volume keys and using decibels. +# Up to max of 6.0 dB in multiples of 0.5 (e.g. 0.5, 1.0, 1.5, etc.). +increment_decibels = 2.0 + +# The amount that the volume should be increased when using the volume keys and holding shift down +# and using decibels. +# Up to max of 3.0 dB in multiples of 0.25 (i.e.. 0.25, 0.5, 0.75, etc.). +fine_increment_decibels = 0.5 + +# The maximum volume to send when using decibels. +# Up to max of 6.0 dB. +max_decibels = 6.0 [theme] # The main widget and tray tooltip background corner rounding and color. diff --git a/src/TotalMixVC.Tests/ConfigTests.cs b/src/TotalMixVC.Tests/ConfigTests.cs index 81077a9..0e45065 100644 --- a/src/TotalMixVC.Tests/ConfigTests.cs +++ b/src/TotalMixVC.Tests/ConfigTests.cs @@ -18,9 +18,12 @@ public void TryFromToml_ValidConfiguration_LoadsAllProperties() [volume] use_decibels = true - increment = 1.0 - fine_increment = 0.5 - max = 0.0 + increment_percent = 0.04 + fine_increment_percent = 0.02 + max_percent = 0.8 + increment_decibels = 1.0 + fine_increment_decibels = 0.5 + max_decibels = 0.0 [theme] background_rounding = 5.0 @@ -55,9 +58,12 @@ out var diagnostics Volume = new Volume() { UseDecibels = true, - Increment = 1.0f, - FineIncrement = 0.5f, - Max = 0.0f, + IncrementPercent = new(0.04f), + FineIncrementPercent = new(0.02f), + MaxPercent = new(0.8f), + IncrementDecibels = new(1.0f), + FineIncrementDecibels = new(0.5f), + MaxDecibels = new(0.0f), }, Theme = new Theme() { @@ -143,6 +149,343 @@ out var diagnostics Assert.Equal(expectedConfig, config); } + [Fact] + public void TryFromToml_ValidVolumeIncrementPercent_LoadsProperty() + { + var isValid = Config.TryFromToml( + """ + [volume] + increment_percent = 0.03 + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { IncrementPercent = new(0.03f) }, + }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(0.30f)] + [InlineData(-0.01f)] + public void TryFromToml_InvalidVolumeIncrementPercent_SkipsLoadingProperty( + float volumeIncrementPercent + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + increment_percent = {volumeIncrementPercent:F2} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { IncrementPercent = new(0.02f) }, + }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + + [Fact] + public void TryFromToml_ValidVolumeFineIncrementPercent_LoadsProperty() + { + var isValid = Config.TryFromToml( + """ + [volume] + fine_increment_percent = 0.01 + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { FineIncrementPercent = new(0.01f) }, + }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(0.10f)] + [InlineData(-0.03f)] + public void TryFromToml_InvalidVolumeFineIncrementPercent_SkipsLoadingProperty( + float volumeFineIncrementPercent + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + fine_increment_percent = {volumeFineIncrementPercent:F2} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { FineIncrementPercent = new(0.01f) }, + }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + + [Fact] + public void TryFromToml_ValidVolumeMaxPercent_LoadsProperty() + { + var isValid = Config.TryFromToml( + """ + [volume] + max_percent = 0.90 + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() { Volume = new Volume() { MaxPercent = new(0.90f) } }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(1.10f)] + [InlineData(-0.15f)] + public void TryFromToml_InvalidVolumeMaxPercent_SkipsLoadingProperty(float volumeMaxPercent) + { + var isValid = Config.TryFromToml( + $""" + [volume] + max_percent = {volumeMaxPercent:F2} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() { Volume = new Volume() { MaxPercent = new(1.0f) } }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(0.5f)] + [InlineData(1.0f)] + [InlineData(1.5f)] + [InlineData(2.0f)] + [InlineData(2.5f)] + [InlineData(4.0f)] + [InlineData(5.0f)] + [InlineData(5.5f)] + public void TryFromToml_ValidVolumeIncrementDecibels_LoadsProperty( + float volumeIncrementDecibels + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + increment_decibels = {volumeIncrementDecibels:F1} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { IncrementDecibels = new(volumeIncrementDecibels) }, + }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(-0.01f)] + [InlineData(0.0f)] + [InlineData(0.25f)] + [InlineData(0.75f)] + [InlineData(1.1f)] + [InlineData(1.25f)] + [InlineData(1.75f)] + [InlineData(2.7f)] + [InlineData(3.1f)] + [InlineData(5.75f)] + [InlineData(6.25f)] + [InlineData(6.5f)] + public void TryFromToml_InvalidVolumeIncrementDecibels_SkipsLoadingProperty( + float volumeIncrementDecibels + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + increment_decibels = {volumeIncrementDecibels:F2} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { IncrementDecibels = new(2.0f) }, + }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(0.25f)] + [InlineData(0.5f)] + [InlineData(1.0f)] + [InlineData(1.25f)] + [InlineData(1.5f)] + [InlineData(2.0f)] + [InlineData(2.75f)] + public void TryFromToml_ValidVolumeFineIncrementDecibels_LoadsProperty( + float volumeFineIncrementDecibels + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + fine_increment_decibels = {volumeFineIncrementDecibels:F2} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { FineIncrementDecibels = new(volumeFineIncrementDecibels) }, + }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(-0.03f)] + [InlineData(0.3f)] + [InlineData(1.1f)] + [InlineData(1.9f)] + [InlineData(3.25f)] + [InlineData(3.5f)] + public void TryFromToml_InvalidVolumeFineIncrementDecibels_SkipsLoadingProperty( + float volumeFineIncrementDecibels + ) + { + var isValid = Config.TryFromToml( + $""" + [volume] + fine_increment_decibels = {volumeFineIncrementDecibels} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { FineIncrementDecibels = new(1.0f) }, + }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(-61.2f)] + [InlineData(-32.0f)] + [InlineData(0.0f)] + [InlineData(3.5f)] + [InlineData(6.0f)] + public void TryFromToml_ValidVolumeMaxDecibels_LoadsProperty(float volumeMaxDecibels) + { + var isValid = Config.TryFromToml( + $""" + [volume] + max_decibels = {volumeMaxDecibels:F1} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() + { + Volume = new Volume() { MaxDecibels = new(volumeMaxDecibels) }, + }; + + Assert.True(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Empty(diagnostics); + Assert.Equal(expectedConfig, config); + } + + [Theory] + [InlineData(6.1f)] + [InlineData(10.0f)] + public void TryFromToml_InvalidVolumeMaxDecibels_SkipsLoadingProperty(float volumeMaxDecibels) + { + var isValid = Config.TryFromToml( + $""" + [volume] + max_decibels = {volumeMaxDecibels:F1} + """, + out var config, + out var diagnostics + ); + + var expectedConfig = new Config() { Volume = new Volume() { MaxDecibels = new(6.0f) } }; + + Assert.False(isValid); + Assert.NotNull(config); + Assert.NotNull(diagnostics); + Assert.Equal(2, diagnostics.Count); + Assert.Equal(expectedConfig, config); + } + [Fact] public void TryFromToml_InvalidDoubles_ResetsPropertiesToDefaults() { diff --git a/src/TotalMixVC.Tests/VolumeManagerTests.cs b/src/TotalMixVC.Tests/VolumeManagerTests.cs index 641573f..fb544e0 100644 --- a/src/TotalMixVC.Tests/VolumeManagerTests.cs +++ b/src/TotalMixVC.Tests/VolumeManagerTests.cs @@ -26,199 +26,7 @@ public void Dispose() } [Fact] - public void Constructor_EnablingUseDecibels_UpdatesDefaults() - { - _volumeManager.UseDecibels = true; - Assert.Equal(2.0f, _volumeManager.VolumeRegularIncrement); - Assert.Equal(1.0f, _volumeManager.VolumeFineIncrement); - Assert.Equal(6.0f, _volumeManager.VolumeMax); - } - - [Fact] - public void Constructor_DisablingUseDecibels_UpdatesDefaults() - { - _volumeManager.UseDecibels = true; - _volumeManager.UseDecibels = false; - Assert.Equal(0.02f, _volumeManager.VolumeRegularIncrement); - Assert.Equal(0.01f, _volumeManager.VolumeFineIncrement); - Assert.Equal(1.0f, _volumeManager.VolumeMax); - } - - [Fact] - public void Constructor_EnablingUseDecibelsMultipleTimes_RetainsValues() - { - _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 2.0f; - _volumeManager.VolumeFineIncrement = 1.0f; - _volumeManager.VolumeMax = 0.0f; - _volumeManager.UseDecibels = true; - Assert.Equal(2.0f, _volumeManager.VolumeRegularIncrement); - Assert.Equal(1.0f, _volumeManager.VolumeFineIncrement); - Assert.Equal(0.0f, _volumeManager.VolumeMax); - } - - [Fact] - public void Constructor_DisablingUseDecibelsMultipleTimes_RetainsValues() - { - _volumeManager.VolumeRegularIncrement = 0.04f; - _volumeManager.VolumeFineIncrement = 0.02f; - _volumeManager.VolumeMax = 0.8f; - _volumeManager.UseDecibels = false; - Assert.Equal(0.04f, _volumeManager.VolumeRegularIncrement); - Assert.Equal(0.02f, _volumeManager.VolumeFineIncrement); - Assert.Equal(0.8f, _volumeManager.VolumeMax); - } - - [Fact] - public void Constructor_ValidVolumeRegularIncrementPercentage_SetsProperty() - { - _volumeManager.VolumeRegularIncrement = 0.03f; - Assert.Equal(0.03f, _volumeManager.VolumeRegularIncrement); - } - - [Theory] - [InlineData(0.25f)] - [InlineData(0.5f)] - [InlineData(0.75f)] - [InlineData(1.0f)] - [InlineData(1.25f)] - [InlineData(1.5f)] - [InlineData(1.75f)] - [InlineData(2.0f)] - [InlineData(2.5f)] - [InlineData(4.0f)] - [InlineData(5.0f)] - [InlineData(5.5f)] - [InlineData(5.75f)] - public void Constructor_ValidVolumeRegularIncrementDecibels_SetsProperty( - float volumeRegularIncrement - ) - { - _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = volumeRegularIncrement; - Assert.Equal(volumeRegularIncrement, _volumeManager.VolumeRegularIncrement); - } - - [Theory] - [InlineData(0.30f)] - [InlineData(-0.01f)] - public void Constructor_InvalidVolumeRegularIncrementPercentage_ThrowsException( - float volumeRegularIncrement - ) - { - Assert.Throws( - () => _volumeManager.VolumeRegularIncrement = volumeRegularIncrement - ); - } - - [Theory] - [InlineData(-0.01f)] - [InlineData(0.0f)] - [InlineData(1.1f)] - [InlineData(2.7f)] - [InlineData(3.1f)] - [InlineData(6.25f)] - [InlineData(6.5f)] - public void Constructor_InvalidVolumeRegularIncrementDecibels_ThrowsException( - float volumeRegularIncrement - ) - { - _volumeManager.UseDecibels = true; - Assert.Throws( - () => _volumeManager.VolumeRegularIncrement = volumeRegularIncrement - ); - } - - [Fact] - public void Constructor_ValidVolumeFineIncrementPercentage_SetsProperty() - { - _volumeManager.VolumeFineIncrement = 0.01f; - Assert.Equal(0.01f, _volumeManager.VolumeFineIncrement); - } - - [Theory] - [InlineData(0.25f)] - [InlineData(0.5f)] - [InlineData(1.0f)] - [InlineData(1.25f)] - [InlineData(1.5f)] - [InlineData(2.0f)] - [InlineData(2.75f)] - public void Constructor_ValidVolumeFineIncrementDecibels_SetsProperty(float volumeFineIncrement) - { - _volumeManager.UseDecibels = true; - _volumeManager.VolumeFineIncrement = volumeFineIncrement; - Assert.Equal(volumeFineIncrement, _volumeManager.VolumeFineIncrement); - } - - [Theory] - [InlineData(0.10f)] - [InlineData(-0.03f)] - public void Constructor_InvalidVolumeFineIncrementPercentage_ThrowsException( - float volumeFineIncrement - ) - { - Assert.Throws( - () => _volumeManager.VolumeFineIncrement = volumeFineIncrement - ); - } - - [Theory] - [InlineData(-0.03f)] - [InlineData(0.3f)] - [InlineData(1.1f)] - [InlineData(1.9f)] - [InlineData(3.25f)] - [InlineData(3.5f)] - public void Constructor_InvalidVolumeFineIncrementDecibels_ThrowsException( - float volumeFineIncrement - ) - { - _volumeManager.UseDecibels = true; - Assert.Throws( - () => _volumeManager.VolumeFineIncrement = volumeFineIncrement - ); - } - - [Fact] - public void Constructor_ValidVolumeMaxPercentage_SetsProperty() - { - _volumeManager.VolumeMax = 0.90f; - Assert.Equal(0.90f, _volumeManager.VolumeMax); - } - - [Theory] - [InlineData(-61.2f)] - [InlineData(-32.0f)] - [InlineData(0.0f)] - [InlineData(3.5f)] - [InlineData(6.0f)] - public void Constructor_ValidVolumeMaxDecibels_SetsProperty(float volumeMax) - { - _volumeManager.UseDecibels = true; - _volumeManager.VolumeMax = volumeMax; - Assert.Equal(volumeMax, _volumeManager.VolumeMax); - } - - [Theory] - [InlineData(1.10f)] - [InlineData(-0.15f)] - public void Constructor_InvalidVolumeMaxPercentage_ThrowsException(float volumeMax) - { - Assert.Throws(() => _volumeManager.VolumeMax = volumeMax); - } - - [Theory] - [InlineData(6.1f)] - [InlineData(10.0f)] - public void Constructor_InvalidVolumeMaxDecibels_ThrowsException(float volumeMax) - { - _volumeManager.UseDecibels = true; - Assert.Throws(() => _volumeManager.VolumeMax = volumeMax); - } - - [Fact] - public async Task RequestVolumeAsync_RegularRequest_RequestsVolume_Async() + public async Task RequestVolumeAsync_Request_RequestsVolume_Async() { await _volumeManager.RequestVolumeAsync(); await _sender @@ -429,14 +237,14 @@ await Assert.ThrowsAsync( } [Fact] - public async Task IncreaseVolumeAsync_RegularVolumeNotInitialized_DoesNotUpdateVolume_Async() + public async Task IncreaseVolumeAsync_VolumeNotInitialized_DoesNotUpdateVolume_Async() { var updated = await _volumeManager.IncreaseVolumeAsync(); Assert.False(updated); } [Fact] - public async Task IncreaseVolumeAsync_RegularAfterVolumeInitializedPercentage_UpdatesVolume_Async() + public async Task IncreaseVolumeAsync_AfterVolumeInitializedPercent_UpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -451,7 +259,9 @@ public async Task IncreaseVolumeAsync_RegularAfterVolumeInitializedPercentage_Up ) ); - _volumeManager.VolumeRegularIncrement = 0.02f; + _volumeManager.VolumeIncrementPercent = 0.02f; + _volumeManager.VolumeMaxPercent = 1.0f; + await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); @@ -471,7 +281,7 @@ await _sender [InlineData(0.19964331f, "-38.2 dB", -38.0f)] [InlineData(0.2372316f, "-34.0 dB", -33.0f)] [InlineData(0.2764855f, "-29.9 dB", -29.0f)] - public async Task IncreaseVolumeAsync_RegularAfterVolumeInitializedDecibels_UpdatesVolume_Async( + public async Task IncreaseVolumeAsync_AfterVolumeInitializedDecibels_UpdatesVolume_Async( float masterVolume, string masterVolumeVal, float expectedUpdatedVolumeDB @@ -491,7 +301,9 @@ float expectedUpdatedVolumeDB ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; + _volumeManager.VolumeIncrementDecibels = 1.0f; + _volumeManager.VolumeMaxDecibels = 6.0f; + await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); var updatedValue = VolumeManager.DecibelsToValue(expectedUpdatedVolumeDB); @@ -509,7 +321,7 @@ await _sender } [Fact] - public async Task IncreaseVolumeAsync_RegularExceedsMaxPercentage_IsCappedAndUpdatesVolume_Async() + public async Task IncreaseVolumeAsync_ExceedsMaxPercent_IsCappedAndUpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -524,8 +336,8 @@ public async Task IncreaseVolumeAsync_RegularExceedsMaxPercentage_IsCappedAndUpd ) ); - _volumeManager.VolumeRegularIncrement = 0.05f; - _volumeManager.VolumeMax = 0.50f; + _volumeManager.VolumeIncrementPercent = 0.05f; + _volumeManager.VolumeMaxPercent = 0.50f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); @@ -543,7 +355,7 @@ await _sender } [Fact] - public async Task IncreaseVolumeAsync_RegularExceedsMaxDecibels_IsCappedAndUpdatesVolume_Async() + public async Task IncreaseVolumeAsync_ExceedsMaxDecibels_IsCappedAndUpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -559,8 +371,8 @@ public async Task IncreaseVolumeAsync_RegularExceedsMaxDecibels_IsCappedAndUpdat ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; - _volumeManager.VolumeMax = -13.0f; + _volumeManager.VolumeIncrementDecibels = 1.0f; + _volumeManager.VolumeMaxDecibels = -13.0f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); @@ -579,7 +391,7 @@ await _sender } [Fact] - public async Task IncreaseVolumeAsync_RegularAlreadyMaxPercentage_DoesNotUpdateVolume_Async() + public async Task IncreaseVolumeAsync_AlreadyMaxPercent_DoesNotUpdateVolume_Async() { _listener .ReceiveAsync(default) @@ -594,8 +406,8 @@ public async Task IncreaseVolumeAsync_RegularAlreadyMaxPercentage_DoesNotUpdateV ) ); - _volumeManager.VolumeRegularIncrement = 0.05f; - _volumeManager.VolumeMax = 0.50f; + _volumeManager.VolumeIncrementPercent = 0.05f; + _volumeManager.VolumeMaxPercent = 0.50f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); @@ -604,7 +416,7 @@ public async Task IncreaseVolumeAsync_RegularAlreadyMaxPercentage_DoesNotUpdateV } [Fact] - public async Task IncreaseVolumeAsync_RegularAlreadyMaxDecibels_DoesNotUpdateVolume_Async() + public async Task IncreaseVolumeAsync_AlreadyMaxDecibels_DoesNotUpdateVolume_Async() { _listener .ReceiveAsync(default) @@ -620,8 +432,8 @@ public async Task IncreaseVolumeAsync_RegularAlreadyMaxDecibels_DoesNotUpdateVol ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; - _volumeManager.VolumeMax = -12.1f; + _volumeManager.VolumeIncrementDecibels = 1.0f; + _volumeManager.VolumeMaxDecibels = -12.1f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(); @@ -637,7 +449,7 @@ public async Task IncreaseVolumeAsync_FineVolumeNotInitialized_DoesNotUpdateVolu } [Fact] - public async Task FineAfterVolumeInitializedPercentage_UpdatesVolume_Async() + public async Task FineAfterVolumeInitializedPercent_UpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -652,7 +464,9 @@ public async Task FineAfterVolumeInitializedPercentage_UpdatesVolume_Async() ) ); - _volumeManager.VolumeFineIncrement = 0.01f; + _volumeManager.VolumeFineIncrementPercent = 0.01f; + _volumeManager.VolumeMaxPercent = 1.0f; + await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(fine: true); @@ -685,7 +499,9 @@ public async Task FineAfterVolumeInitializedDecibels_UpdatesVolume_Async() ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeFineIncrement = 0.5f; + _volumeManager.VolumeFineIncrementDecibels = 0.5f; + _volumeManager.VolumeMaxDecibels = 6.0f; + await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.IncreaseVolumeAsync(fine: true); var updatedValue = VolumeManager.DecibelsToValue(-38.5f); @@ -703,14 +519,14 @@ await _sender } [Fact] - public async Task DecreaseVolumeAsync_RegularVolumeNotInitialized_DoesNotUpdateVolume_Async() + public async Task DecreaseVolumeAsync_VolumeNotInitialized_DoesNotUpdateVolume_Async() { var updated = await _volumeManager.DecreaseVolumeAsync(); Assert.False(updated); } [Fact] - public async Task DecreaseVolumeAsync_RegularAfterVolumeInitializedPercentage_UpdatesVolume_Async() + public async Task DecreaseVolumeAsync_AfterVolumeInitializedPercent_UpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -725,7 +541,7 @@ public async Task DecreaseVolumeAsync_RegularAfterVolumeInitializedPercentage_Up ) ); - _volumeManager.VolumeRegularIncrement = 0.02f; + _volumeManager.VolumeIncrementPercent = 0.02f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); @@ -742,7 +558,7 @@ await _sender } [Fact] - public async Task DecreaseVolumeAsync_RegularAfterVolumeInitializedDecibels_UpdatesVolume_Async() + public async Task DecreaseVolumeAsync_AfterVolumeInitializedDecibels_UpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -758,7 +574,7 @@ public async Task DecreaseVolumeAsync_RegularAfterVolumeInitializedDecibels_Upda ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; + _volumeManager.VolumeIncrementDecibels = 1.0f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); var updatedValue = VolumeManager.DecibelsToValue(-13.0f); @@ -776,7 +592,7 @@ await _sender } [Fact] - public async Task DecreaseVolumeAsync_RegularBelowSilentPercentage_IsSetToSilentAndUpdatesVolume_Async() + public async Task DecreaseVolumeAsync_BelowSilentPercent_IsSetToSilentAndUpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -791,7 +607,7 @@ public async Task DecreaseVolumeAsync_RegularBelowSilentPercentage_IsSetToSilent ) ); - _volumeManager.VolumeRegularIncrement = 0.05f; + _volumeManager.VolumeIncrementPercent = 0.05f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); @@ -808,7 +624,7 @@ await _sender } [Fact] - public async Task DecreaseVolumeAsync_RegularBelowSilentDecibels_IsSetToSilentAndUpdatesVolume_Async() + public async Task DecreaseVolumeAsync_BelowSilentDecibels_IsSetToSilentAndUpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -824,7 +640,7 @@ public async Task DecreaseVolumeAsync_RegularBelowSilentDecibels_IsSetToSilentAn ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; + _volumeManager.VolumeIncrementDecibels = 1.0f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); @@ -841,7 +657,7 @@ await _sender } [Fact] - public async Task DecreaseVolumeAsync_RegularAlreadySilentPercentage_DoesNotUpdateVolume_Async() + public async Task DecreaseVolumeAsync_AlreadySilentPercent_DoesNotUpdateVolume_Async() { _listener .ReceiveAsync(default) @@ -856,7 +672,7 @@ public async Task DecreaseVolumeAsync_RegularAlreadySilentPercentage_DoesNotUpda ) ); - _volumeManager.VolumeRegularIncrement = 0.05f; + _volumeManager.VolumeIncrementPercent = 0.05f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); @@ -865,7 +681,7 @@ public async Task DecreaseVolumeAsync_RegularAlreadySilentPercentage_DoesNotUpda } [Fact] - public async Task DecreaseVolumeAsync_RegularAlreadySilentDecibels_DoesNotUpdateVolume_Async() + public async Task DecreaseVolumeAsync_AlreadySilentDecibels_DoesNotUpdateVolume_Async() { _listener .ReceiveAsync(default) @@ -881,7 +697,7 @@ public async Task DecreaseVolumeAsync_RegularAlreadySilentDecibels_DoesNotUpdate ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeRegularIncrement = 1.0f; + _volumeManager.VolumeIncrementDecibels = 1.0f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(); @@ -897,7 +713,7 @@ public async Task DecreaseVolumeAsync_FineVolumeNotInitialized_DoesNotUpdateVolu } [Fact] - public async Task DecreaseVolumeAsync_FineAfterVolumeInitializedPercentage_UpdatesVolume_Async() + public async Task DecreaseVolumeAsync_FineAfterVolumeInitializedPercent_UpdatesVolume_Async() { _listener .ReceiveAsync(default) @@ -912,7 +728,7 @@ public async Task DecreaseVolumeAsync_FineAfterVolumeInitializedPercentage_Updat ) ); - _volumeManager.VolumeFineIncrement = 0.01f; + _volumeManager.VolumeFineIncrementPercent = 0.01f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(fine: true); @@ -945,7 +761,7 @@ public async Task DecreaseVolumeAsync_FineAfterVolumeInitializedDecibels_Updates ); _volumeManager.UseDecibels = true; - _volumeManager.VolumeFineIncrement = 0.5f; + _volumeManager.VolumeFineIncrementDecibels = 0.5f; await _volumeManager.ReceiveVolumeAsync(); var updated = await _volumeManager.DecreaseVolumeAsync(fine: true); var updateValue = VolumeManager.DecibelsToValue(-39.0f); diff --git a/src/TotalMixVC/App.xaml.cs b/src/TotalMixVC/App.xaml.cs index 27ff979..57b000c 100644 --- a/src/TotalMixVC/App.xaml.cs +++ b/src/TotalMixVC/App.xaml.cs @@ -188,7 +188,7 @@ public void ReloadConfig() _volumeManager.OutgoingEndpoint = _config.Osc.OutgoingEndPoint; - ConfigureVolumeManager(running: true); + ConfigureVolumeManager(); ConfigureInterface(); ConfigureTheme(); @@ -294,7 +294,7 @@ protected override void OnStartup(StartupEventArgs e) return; } - ConfigureVolumeManager(running: false); + ConfigureVolumeManager(); // Start a task that will receive and record volume changes. _volumeReceiveTask = _joinableTaskFactory.RunAsync(ReceiveVolumeAsync); @@ -531,88 +531,15 @@ private void RegisterHotkeys() ); } - private void ConfigureVolumeManager(bool running = false) + private void ConfigureVolumeManager() { - var exceptions = new List(); - _volumeManager.UseDecibels = _config.Volume.UseDecibels; - - if (_config.Volume.Increment is float volumeIncrement) - { - try - { - _volumeManager.VolumeRegularIncrement = volumeIncrement; - } - catch (ArgumentOutOfRangeException ex) - { - exceptions.Add(ex); - } - } - - if (_config.Volume.FineIncrement is float fineIncrement) - { - try - { - _volumeManager.VolumeFineIncrement = fineIncrement; - } - catch (ArgumentOutOfRangeException ex) - { - exceptions.Add(ex); - } - } - - if (_config.Volume.Max is float volumeMax) - { - try - { - _volumeManager.VolumeMax = volumeMax; - } - catch (ArgumentOutOfRangeException ex) - { - exceptions.Add(ex); - } - } - - if (exceptions.Count > 0) - { - var configDescription = running ? "existing" : "default"; - var message = new StringBuilder(); - - message.Append( - CultureInfo.InvariantCulture, - $"Unable to configure the volume based on the config file at {s_configPath}.\n\n" - ); - - foreach (var exception in exceptions) - { - message.Append(CultureInfo.InvariantCulture, $"- {exception.Message}\n"); - } - - message.Append( - CultureInfo.InvariantCulture, - $"\nThe application will continue with the {configDescription} values for affected properties." - ); - - if (running) - { - MessageBox.Show( - _volumeIndicator, - message.ToString(), - caption: "Configuration File Error", - button: MessageBoxButton.OK, - icon: MessageBoxImage.Exclamation - ); - } - else - { - MessageBox.Show( - message.ToString(), - caption: "Configuration File Error", - button: MessageBoxButton.OK, - icon: MessageBoxImage.Exclamation - ); - } - } + _volumeManager.VolumeIncrementPercent = _config.Volume.IncrementPercent.Value; + _volumeManager.VolumeFineIncrementPercent = _config.Volume.FineIncrementPercent.Value; + _volumeManager.VolumeMaxPercent = _config.Volume.MaxPercent.Value; + _volumeManager.VolumeIncrementDecibels = _config.Volume.IncrementDecibels.Value; + _volumeManager.VolumeFineIncrementDecibels = _config.Volume.FineIncrementDecibels.Value; + _volumeManager.VolumeMaxDecibels = _config.Volume.MaxDecibels.Value; } private void ConfigureInterface() diff --git a/src/TotalMixVC/Communicator/VolumeManager.cs b/src/TotalMixVC/Communicator/VolumeManager.cs index 3edfdd6..248f9a7 100644 --- a/src/TotalMixVC/Communicator/VolumeManager.cs +++ b/src/TotalMixVC/Communicator/VolumeManager.cs @@ -30,14 +30,6 @@ public class VolumeManager : IDisposable private readonly IListener _listener; - private bool _useDecibels; - - private float _volumeRegularIncrement = 0.02f; - - private float _volumeFineIncrement = 0.01f; - - private float _volumeMax = 1.0f; - /// /// Initializes a new instance of the class. /// @@ -99,133 +91,43 @@ public IPEndPoint OutgoingEndpoint /// /// Gets or sets a value indicating whether volume units are set in dB instead of percentages. /// - public bool UseDecibels - { - get => _useDecibels; - set - { - if (_useDecibels != value) - { - if (value) - { - _volumeRegularIncrement = 2.0f; - _volumeFineIncrement = 1.0f; - _volumeMax = 6.0f; - } - else - { - _volumeRegularIncrement = 0.02f; - _volumeFineIncrement = 0.01f; - _volumeMax = 1.0f; - } - } - - _useDecibels = value; - } - } + public bool UseDecibels { get; set; } /// - /// Gets or sets the increment to use when regularly increasing or decreasing the volume. + /// Gets or sets the increment to use when increasing or decreasing the volume + /// in percent. /// - /// - /// The regular volume increment is not within the required range. - /// - /// - /// When the regular increment specified is not in the supported range. - /// - public float VolumeRegularIncrement - { - get => _volumeRegularIncrement; - set - { - if (_useDecibels && (value <= 0.0 || value > 6.0 || value % 0.25f != 0.0f)) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified dB volume increment must be a multiple of 0.25 while being greater " - + "than 0 and less than or equal to 6.0." - ); - } - else if (!_useDecibels && value is <= 0.0f or > 0.10f) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified volume increment must be greater than 0 and less than or equal " - + "to 0.1." - ); - } + public float VolumeIncrementPercent { get; set; } - _volumeRegularIncrement = value; - } - } + /// + /// Gets or sets the increment to use when finely increasing or decreasing the volume + /// in percent. + /// + public float VolumeFineIncrementPercent { get; set; } /// - /// Gets or sets the increment to use when finely increasing or decreasing the volume. + /// Gets or sets the maximum volume that should be allowed when increasing the volume + /// in percent. /// - /// - /// The fine volume increment is not within the required range. - /// - /// - /// When the fine increment specified is not in the supported range. - /// - public float VolumeFineIncrement - { - get => _volumeFineIncrement; - set - { - if (_useDecibels && (value <= 0.0 || value > 3.0 || value % 0.25f != 0.0f)) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified fine dB volume increment must be a multiple of 0.25 while being " - + "greater than 0 and less than or equal to 3.0." - ); - } - else if (!_useDecibels && value is <= 0.0f or > 0.05f) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified fine volume increment must be greater than 0 and less than or " - + "equal to 0.05." - ); - } + public float VolumeMaxPercent { get; set; } - _volumeFineIncrement = value; - } - } + /// + /// Gets or sets the increment to use when increasing or decreasing the volume + /// in decibels. + /// + public float VolumeIncrementDecibels { get; set; } /// - /// Gets or sets the maximum volume that should be allowed when increasing the volume. + /// Gets or sets the increment to use when finely increasing or decreasing the volume + /// in decibels. /// - /// - /// The max volume increment not within the required range. - /// - /// - /// When the max volume specified is not in the supported range. - /// - public float VolumeMax - { - get => _volumeMax; - set - { - if (_useDecibels && value is > 6.0f) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified max dB volume must be less than or equal to 6.0." - ); - } - else if (!_useDecibels && value is <= 0.0f or > 1.0f) - { - throw new ArgumentOutOfRangeException( - nameof(value), - "Specified max volume must be greater than 0 and less than or equal to 1.0." - ); - } + public float VolumeFineIncrementDecibels { get; set; } - _volumeMax = value; - } - } + /// + /// Gets or sets the maximum volume that should be allowed when increasing the volume + /// in decibels. + /// + public float VolumeMaxDecibels { get; set; } /// /// Gets a value indicating whether the volume has been obtained from the device at least @@ -351,31 +253,33 @@ public async Task IncreaseVolumeAsync(bool fine = false) try { // Calculate the new volume. - var increment = fine ? _volumeFineIncrement : _volumeRegularIncrement; - float newVolume; if (UseDecibels) { + var increment = fine ? VolumeFineIncrementDecibels : VolumeIncrementDecibels; + var volumeDB = MathF.Floor(MathF.Round(ValueToDecibels(Volume) / increment, 1)) * increment; volumeDB += increment; // Ensure it doesn't exceed the max dB. - if (volumeDB >= VolumeMax) + if (volumeDB >= VolumeMaxDecibels) { - volumeDB = VolumeMax; + volumeDB = VolumeMaxDecibels; } newVolume = DecibelsToValue(volumeDB); } else { + var increment = fine ? VolumeFineIncrementPercent : VolumeIncrementPercent; + newVolume = Volume + increment; // Ensure it doesn't exceed the max. - if (newVolume >= VolumeMax) + if (newVolume >= VolumeMaxPercent) { - newVolume = VolumeMax; + newVolume = VolumeMaxPercent; } } @@ -414,17 +318,20 @@ public async Task DecreaseVolumeAsync(bool fine = false) try { // Calculate the new volume. - var increment = fine ? VolumeFineIncrement : VolumeRegularIncrement; float newVolume; if (UseDecibels) { + var increment = fine ? VolumeFineIncrementDecibels : VolumeIncrementDecibels; + var volumeDB = MathF.Ceiling(MathF.Round(ValueToDecibels(Volume) / increment, 1)) * increment; volumeDB -= increment; + newVolume = DecibelsToValue(volumeDB); } else { + var increment = fine ? VolumeFineIncrementPercent : VolumeIncrementPercent; newVolume = Volume - increment; } diff --git a/src/TotalMixVC/Configuration/Config.cs b/src/TotalMixVC/Configuration/Config.cs index 0319a65..20b5b95 100644 --- a/src/TotalMixVC/Configuration/Config.cs +++ b/src/TotalMixVC/Configuration/Config.cs @@ -2,6 +2,7 @@ using System.Windows.Media; using Tomlyn; using Tomlyn.Syntax; +using TotalMixVC.Configuration.Models; namespace TotalMixVC.Configuration; @@ -44,6 +45,20 @@ public static bool TryFromToml(string text, out Config? config, out DiagnosticsB string color when type == typeof(Color) => (Color) ColorConverter.ConvertFromString(color)!, string address when type == typeof(IPEndPoint) => IPEndPoint.Parse(address), + double increment when type == typeof(VolumeIncrementPercent) => + new VolumeIncrementPercent((float)increment), + double increment when type == typeof(VolumeFineIncrementPercent) => + new VolumeFineIncrementPercent((float)increment), + double max when type == typeof(VolumeMaxPercent) => new VolumeMaxPercent( + (float)max + ), + double increment when type == typeof(VolumeIncrementDecibels) => + new VolumeIncrementDecibels((float)increment), + double increment when type == typeof(VolumeFineIncrementDecibels) => + new VolumeFineIncrementDecibels((float)increment), + double max when type == typeof(VolumeMaxDecibels) => new VolumeMaxDecibels( + (float)max + ), _ => null, }, } diff --git a/src/TotalMixVC/Configuration/Models/VolumeFineIncrementDecibels.cs b/src/TotalMixVC/Configuration/Models/VolumeFineIncrementDecibels.cs new file mode 100644 index 0000000..64fe517 --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeFineIncrementDecibels.cs @@ -0,0 +1,40 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the increment to use when finely increasing or decreasing the volume in decibels. +/// +public record VolumeFineIncrementDecibels +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume decibel value. + public VolumeFineIncrementDecibels(float value) + { + Value = value; + } + + /// Gets or sets the volume decibel value. + /// + /// The fine increment specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value <= 0.0 || value > 3.0 || value % 0.25f != 0.0f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be a multiple of 0.25 while being greater than 0 and less than or equal " + + "to 3.0." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Models/VolumeFineIncrementPercent.cs b/src/TotalMixVC/Configuration/Models/VolumeFineIncrementPercent.cs new file mode 100644 index 0000000..15c98f1 --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeFineIncrementPercent.cs @@ -0,0 +1,39 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the increment to use when finely increasing or decreasing the volume in percent. +/// +public record VolumeFineIncrementPercent +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume percentage value. + public VolumeFineIncrementPercent(float value) + { + Value = value; + } + + /// Gets or sets the volume percentage value. + /// + /// The fine increment specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value is <= 0.0f or > 0.05f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be greater than 0 and less than or equal to 0.05." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Models/VolumeIncrementDecibels.cs b/src/TotalMixVC/Configuration/Models/VolumeIncrementDecibels.cs new file mode 100644 index 0000000..dd18c4d --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeIncrementDecibels.cs @@ -0,0 +1,40 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the increment to use when increasing or decreasing the volume in decibels. +/// +public record VolumeIncrementDecibels +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume decibel value. + public VolumeIncrementDecibels(float value) + { + Value = value; + } + + /// Gets or sets the volume decibel value. + /// + /// The increment specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value <= 0.0 || value > 6.0 || value % 0.5f != 0.0f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be a multiple of 0.5 while being greater than 0 and less than or equal " + + "to 6.0." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Models/VolumeIncrementPercent.cs b/src/TotalMixVC/Configuration/Models/VolumeIncrementPercent.cs new file mode 100644 index 0000000..f09d713 --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeIncrementPercent.cs @@ -0,0 +1,39 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the increment to use when increasing or decreasing the volume in percent. +/// +public record VolumeIncrementPercent +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume percentage value. + public VolumeIncrementPercent(float value) + { + Value = value; + } + + /// Gets or sets the volume percentage value. + /// + /// The increment specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value is <= 0.0f or > 0.10f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be greater than 0 and less than or equal to 0.1." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Models/VolumeMaxDecibels.cs b/src/TotalMixVC/Configuration/Models/VolumeMaxDecibels.cs new file mode 100644 index 0000000..ff53f3d --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeMaxDecibels.cs @@ -0,0 +1,39 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the maximum volume that should be allowed when increasing the volume in decibels. +/// +public record VolumeMaxDecibels +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume decibel value. + public VolumeMaxDecibels(float value) + { + Value = value; + } + + /// Gets or sets the volume decibel value. + /// + /// The max volume specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value is > 6.0f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be less than or equal to 6.0." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Models/VolumeMaxPercent.cs b/src/TotalMixVC/Configuration/Models/VolumeMaxPercent.cs new file mode 100644 index 0000000..8d8da76 --- /dev/null +++ b/src/TotalMixVC/Configuration/Models/VolumeMaxPercent.cs @@ -0,0 +1,39 @@ +namespace TotalMixVC.Configuration.Models; + +/// +/// Provides the maximum volume that should be allowed when increasing the volume in percent. +/// +public record VolumeMaxPercent +{ + private float _value; + + /// + /// Initializes a new instance of the class. + /// + /// The volume percentage value. + public VolumeMaxPercent(float value) + { + Value = value; + } + + /// Gets or sets the volume percentage value. + /// + /// The max volume specified is not in the supported range. + /// + public float Value + { + get => _value; + set + { + if (value is <= 0.0f or > 1.0f) + { + throw new ArgumentOutOfRangeException( + nameof(value), + "Must be greater than 0 and less than or equal to 1.0." + ); + } + + _value = value; + } + } +} diff --git a/src/TotalMixVC/Configuration/Volume.cs b/src/TotalMixVC/Configuration/Volume.cs index 53b7049..0811158 100644 --- a/src/TotalMixVC/Configuration/Volume.cs +++ b/src/TotalMixVC/Configuration/Volume.cs @@ -1,4 +1,6 @@ -namespace TotalMixVC.Configuration; +using TotalMixVC.Configuration.Models; + +namespace TotalMixVC.Configuration; /// Provides configuration related to volume changes on the device. public record Volume @@ -9,24 +11,40 @@ public record Volume public bool UseDecibels { get; set; } /// - /// Gets or sets the increment that is to be used when adjusting the volume. The volume ranges - /// from 0.0 and 1.0 and thus the max allowed increment is 0.10 for percentages or 3.0 in - /// decibels to avoid major jumps in volume. + /// Gets or sets the increment that is to be used when adjusting the volume in percent. The + /// volume ranges from 0.0 and 1.0 and thus the max allowed increment is 0.10 to avoid major + /// jumps in volume. /// - public float? Increment { get; set; } + public VolumeIncrementPercent IncrementPercent { get; set; } = new(0.02f); /// /// Gets or sets the fine increment that is to be used when adjusting the volume and holding /// the Shift key. The volume ranges from 0.0 and 1.0 and thus the max allowed fine increment - /// is 0.05 for percentages and 1.5 in decibels to avoid major jumps in volume. When using - /// decibels, it is generally a good idea to ensure the fine increment is a multiple of - /// increment. + /// is 0.05 to avoid major jumps in volume. + /// + public VolumeFineIncrementPercent FineIncrementPercent { get; set; } = new(0.01f); + + /// + /// Gets or sets the maximum volume that will be sent by the application where 1.0 is + /// the loudest volume the device can receive. + /// + public VolumeMaxPercent MaxPercent { get; set; } = new(1.0f); + + /// + /// Gets or sets the increment that is to be used when adjusting the volume. The max allowed + /// increment is 3.0 dB to avoid major jumps in volume. + /// + public VolumeIncrementDecibels IncrementDecibels { get; set; } = new(2.0f); + + /// + /// Gets or sets the fine increment that is to be used when adjusting the volume and holding + /// the Shift key. The max allowed fine increment is 1.5 dB to avoid major jumps in volume. /// - public float? FineIncrement { get; set; } + public VolumeFineIncrementDecibels FineIncrementDecibels { get; set; } = new(1.0f); /// - /// Gets or sets the maximum volume that will be sent by the application where 1.0 or 6.0 dB is + /// Gets or sets the maximum volume that will be sent by the application where 6.0 dB is /// the loudest volume the device can receive. /// - public float? Max { get; set; } + public VolumeMaxDecibels MaxDecibels { get; set; } = new(6.0f); }