Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limiter filter outputCeiling + attackTime #170

Merged
merged 3 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name": "Flutter debug",
"type": "dart",
"request": "launch",
"program": "lib/main.dart",
"program": "lib/filters/limiter.dart",
"flutterMode": "debug",
"cwd": "${workspaceFolder}/example"
},
Expand Down
64 changes: 47 additions & 17 deletions example/lib/filters/limiter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import 'package:logging/logging.dart';
/// - `wet`: Wet/dry mix ratio, 1.0 means fully wet, 0.0 means fully dry
/// - `threshold`: The threshold in dB. Signals above this level are reduced
/// in gain. A lower value means more aggressive limiting.
/// - `makeupGain`: The make-up gain in dB applied after limiting to bring up
/// the output level.
/// - `outputCeiling`: The maximum output level in dB (should be < 0dB to
/// prevent clipping)
/// - `kneeWidth`: The width of the knee in dB. A larger value results in a
/// softer transition into limiting.
/// - `releaseTime`: The release time in milliseconds. Determines how quickly
Expand Down Expand Up @@ -72,9 +72,10 @@ class _LimiterExampleState extends State<LimiterExample> {
AudioSource? sound;
late double wet;
late double threshold;
late double makeupGain;
late double outputCeiling;
late double kneeWidth;
late double releaseTime;
late double attackTime;
bool isFilterActive = false;

@override
Expand All @@ -83,9 +84,10 @@ class _LimiterExampleState extends State<LimiterExample> {

wet = limiter.queryWet.def;
threshold = limiter.queryThreshold.def;
makeupGain = limiter.queryMakeupGain.def;
outputCeiling = limiter.queryOutputCeiling.def;
kneeWidth = limiter.queryKneeWidth.def;
releaseTime = limiter.queryReleaseTime.def;
attackTime = limiter.queryAttackTime.def;
}

@override
Expand All @@ -105,7 +107,11 @@ class _LimiterExampleState extends State<LimiterExample> {
children: [
const Text(
'WARNING: lower the volume down!',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
Row(
mainAxisSize: MainAxisSize.min,
Expand All @@ -118,9 +124,10 @@ class _LimiterExampleState extends State<LimiterExample> {
limiter.activate();
limiter.wet.value = wet;
limiter.threshold.value = threshold;
limiter.makeupGain.value = makeupGain;
limiter.outputCeiling.value = outputCeiling;
limiter.kneeWidth.value = kneeWidth;
limiter.releaseTime.value = releaseTime;
limiter.attackTime.value = attackTime;
} else {
limiter.deactivate();
}
Expand All @@ -143,11 +150,16 @@ class _LimiterExampleState extends State<LimiterExample> {
///
ElevatedButton(
onPressed: () {
SoLoud.instance.play(sound!, looping: true);
SoLoud.instance.play(sound!, looping: true);
SoLoud.instance.play(sound!, looping: true);
SoLoud.instance.play(sound!, looping: true);
SoLoud.instance.play(sound!, looping: true);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
SoLoud.instance.play(sound!, looping: true, volume: 2);
},
child: const Text('play sound'),
),
Expand Down Expand Up @@ -199,16 +211,16 @@ class _LimiterExampleState extends State<LimiterExample> {
),
Row(
children: [
Text('Makeup gain ${makeupGain.toStringAsFixed(2)}'),
Text('Outpout ceiling ${outputCeiling.toStringAsFixed(2)}'),
Expanded(
child: Slider(
value: makeupGain,
min: limiter.queryMakeupGain.min,
max: limiter.queryMakeupGain.max,
value: outputCeiling,
min: limiter.queryOutputCeiling.min,
max: limiter.queryOutputCeiling.max,
onChanged: (value) {
setState(() {
makeupGain = value;
limiter.makeupGain.value = value;
outputCeiling = value;
limiter.outputCeiling.value = value;
});
},
),
Expand Down Expand Up @@ -251,6 +263,24 @@ class _LimiterExampleState extends State<LimiterExample> {
),
],
),
Row(
children: [
Text('Attack time ${attackTime.toStringAsFixed(2)}'),
Expanded(
child: Slider(
value: attackTime,
min: limiter.queryAttackTime.min,
max: limiter.queryAttackTime.max,
onChanged: (value) {
setState(() {
attackTime = value;
limiter.attackTime.value = value;
});
},
),
),
],
),
],
),
),
Expand Down
1 change: 0 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:developer' as dev;

import 'package:flutter/foundation.dart';
Expand Down
9 changes: 5 additions & 4 deletions lib/src/filter_params.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ const FxParams fxLimiter = (
names: [
'Wet',
'Threshold',
'Makeup Gain',
'Output Ceiling',
'Knee Width',
'Release Time',
'Attack Time',
],
mins: [0, -60, -60, 0, 1],
maxs: [1, 0, 30, 30, 1000],
defs: [1, -6, 0, 2, 100],
mins: [0, -60, -60, 0, 1, 0.1],
maxs: [1, 0, 30, 0, 1000, 200],
defs: [1, -6, 0, -1, 100, 1],
);

/// Compressor filter
Expand Down
11 changes: 7 additions & 4 deletions lib/src/filters/filters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,15 @@ final class FiltersSingle {
/// - `threshold`: The threshold in dB. Signals above this level are reduced
/// in gain. A lower value means more aggressive limiting.
///
/// - `makeupGain`: The make-up gain in dB applied after limiting to bring up
/// the output level.
/// - `outputCeiling`: The maximum output level in dB (should be < 0dB to
/// prevent clipping)
///
/// - `kneeWidth`: The width of the knee in dB. A larger value results in a
/// softer transition into limiting.
///
/// - `attackTime`: The attack time in milliseconds. Determines how quickly
/// the gain reduction recovers after a signal peaks above the threshold.
///
/// - `releaseTime`: The release time in milliseconds. Determines how quickly
/// the gain reduction recovers after a signal drops below the threshold.
LimiterSingle get limiterFilter => LimiterSingle(soundHash);
Expand Down Expand Up @@ -188,8 +191,8 @@ final class FiltersGlobal {
/// - `threshold`: The threshold in dB. Signals above this level are reduced
/// in gain. A lower value means more aggressive limiting.
///
/// - `makeupGain`: The make-up gain in dB applied after limiting to bring up
/// the output level.
/// - `outputCeiling`: The maximum output level in dB (should be < 0dB to
/// prevent clipping)
///
/// - `kneeWidth`: The width of the knee in dB. A larger value results in a
/// softer transition into limiting.
Expand Down
49 changes: 34 additions & 15 deletions lib/src/filters/limiter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import 'package:flutter_soloud/src/sound_hash.dart';
enum Limiter {
wet,
threshold,
makeupGain,
outputCeiling,
kneeWidth,
releaseTime;
releaseTime,
attackTime;

final List<double> _mins = const [0, -60, -60, 0, 1];
final List<double> _maxs = const [1, 0, 30, 30, 1000];
final List<double> _defs = const [1, -6, 0, 2, 100];
final List<double> _mins = const [0, -60, -60, 0, 1, 0.1];
final List<double> _maxs = const [1, 0, 0, 30, 1000, 200];
final List<double> _defs = const [1, -6, -1, 2, 100, 1];

double get min => _mins[index];
double get max => _maxs[index];
Expand All @@ -23,9 +24,10 @@ enum Limiter {
String toString() => switch (this) {
Limiter.wet => 'Wet',
Limiter.threshold => 'Threshold',
Limiter.makeupGain => 'Makeup Gain',
Limiter.outputCeiling => 'Output Ceiling',
Limiter.kneeWidth => 'Knee Width',
Limiter.releaseTime => 'Release Time',
Limiter.attackTime => 'Attack Time',
};
}

Expand All @@ -35,9 +37,10 @@ abstract class _LimiterInternal extends FilterBase {

Limiter get queryWet => Limiter.wet;
Limiter get queryThreshold => Limiter.threshold;
Limiter get queryMakeupGain => Limiter.makeupGain;
Limiter get queryOutputCeiling => Limiter.outputCeiling;
Limiter get queryKneeWidth => Limiter.kneeWidth;
Limiter get queryReleaseTime => Limiter.releaseTime;
Limiter get queryAttackTime => Limiter.attackTime;
}

class LimiterSingle extends _LimiterInternal {
Expand All @@ -59,12 +62,12 @@ class LimiterSingle extends _LimiterInternal {
Limiter.threshold.max,
);

FilterParam makeupGain({SoundHandle? soundHandle}) => FilterParam(
FilterParam outputCeiling({SoundHandle? soundHandle}) => FilterParam(
soundHandle,
filterType,
Limiter.makeupGain.index,
Limiter.makeupGain.min,
Limiter.makeupGain.max,
Limiter.outputCeiling.index,
Limiter.outputCeiling.min,
Limiter.outputCeiling.max,
);

FilterParam kneeWidth({SoundHandle? soundHandle}) => FilterParam(
Expand All @@ -82,6 +85,14 @@ class LimiterSingle extends _LimiterInternal {
Limiter.releaseTime.min,
Limiter.releaseTime.max,
);

FilterParam attackTime({SoundHandle? soundHandle}) => FilterParam(
soundHandle,
filterType,
Limiter.attackTime.index,
Limiter.attackTime.min,
Limiter.attackTime.max,
);
}

class LimiterGlobal extends _LimiterInternal {
Expand All @@ -103,12 +114,12 @@ class LimiterGlobal extends _LimiterInternal {
Limiter.threshold.max,
);

FilterParam get makeupGain => FilterParam(
FilterParam get outputCeiling => FilterParam(
null,
filterType,
Limiter.makeupGain.index,
Limiter.makeupGain.min,
Limiter.makeupGain.max,
Limiter.outputCeiling.index,
Limiter.outputCeiling.min,
Limiter.outputCeiling.max,
);

FilterParam get kneeWidth => FilterParam(
Expand All @@ -126,4 +137,12 @@ class LimiterGlobal extends _LimiterInternal {
Limiter.releaseTime.min,
Limiter.releaseTime.max,
);

FilterParam get attackTime => FilterParam(
null,
filterType,
Limiter.attackTime.index,
Limiter.attackTime.min,
Limiter.attackTime.max,
);
}
Loading
Loading