mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-05 02:28:36 +02:00
feat(audio): use VHQ settings for SoXR resampling
This commit is contained in:
@@ -595,7 +595,7 @@ class FFmpegService {
|
|||||||
if (!hasSampleRate && !hasSampleFormat && !processing.hasDither) return;
|
if (!hasSampleRate && !hasSampleFormat && !processing.hasDither) return;
|
||||||
|
|
||||||
final options = <String>[
|
final options = <String>[
|
||||||
'resampler=${processing.normalizedResampler}',
|
...losslessResamplerFilterOptions(processing),
|
||||||
if (hasSampleRate) 'osr=$targetSampleRate',
|
if (hasSampleRate) 'osr=$targetSampleRate',
|
||||||
if (hasSampleFormat) 'osf=${outputSampleFormat.trim()}',
|
if (hasSampleFormat) 'osf=${outputSampleFormat.trim()}',
|
||||||
if (processing.hasDither) 'dither_method=${processing.normalizedDither}',
|
if (processing.hasDither) 'dither_method=${processing.normalizedDither}',
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ const List<String> losslessDitherOptions = [
|
|||||||
|
|
||||||
const List<String> losslessResamplerOptions = ['swr', 'soxr'];
|
const List<String> losslessResamplerOptions = ['swr', 'soxr'];
|
||||||
|
|
||||||
|
const int soxrVhqPrecisionBits = 28;
|
||||||
|
const double soxrPassbandEndRatio = 0.95;
|
||||||
|
|
||||||
class LosslessConversionProcessing {
|
class LosslessConversionProcessing {
|
||||||
final String dither;
|
final String dither;
|
||||||
final String resampler;
|
final String resampler;
|
||||||
@@ -49,6 +52,19 @@ class LosslessConversionProcessing {
|
|||||||
bool get hasDither => normalizedDither != 'none';
|
bool get hasDither => normalizedDither != 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> losslessResamplerFilterOptions(
|
||||||
|
LosslessConversionProcessing processing,
|
||||||
|
) {
|
||||||
|
final resampler = processing.normalizedResampler;
|
||||||
|
return [
|
||||||
|
'resampler=$resampler',
|
||||||
|
if (resampler == 'soxr') ...[
|
||||||
|
'precision=$soxrVhqPrecisionBits',
|
||||||
|
'cutoff=$soxrPassbandEndRatio',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
List<int> availableLosslessBitDepthOptions(int? sourceBitDepth) {
|
List<int> availableLosslessBitDepthOptions(int? sourceBitDepth) {
|
||||||
if (sourceBitDepth == null || sourceBitDepth <= 0) {
|
if (sourceBitDepth == null || sourceBitDepth <= 0) {
|
||||||
return losslessConversionBitDepthOptions;
|
return losslessConversionBitDepthOptions;
|
||||||
|
|||||||
@@ -44,6 +44,18 @@ void main() {
|
|||||||
expect(swrHighPass.normalizedDither, 'triangular_hp');
|
expect(swrHighPass.normalizedDither, 'triangular_hp');
|
||||||
expect(swrHighPass.hasDither, isTrue);
|
expect(swrHighPass.hasDither, isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('uses VHQ and a 95 percent passband only for SoXR', () {
|
||||||
|
const soxr = LosslessConversionProcessing(resampler: 'soxr');
|
||||||
|
const swr = LosslessConversionProcessing(resampler: 'swr');
|
||||||
|
|
||||||
|
expect(losslessResamplerFilterOptions(soxr), [
|
||||||
|
'resampler=soxr',
|
||||||
|
'precision=28',
|
||||||
|
'cutoff=0.95',
|
||||||
|
]);
|
||||||
|
expect(losslessResamplerFilterOptions(swr), ['resampler=swr']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('kept conversion output identity', () {
|
group('kept conversion output identity', () {
|
||||||
|
|||||||
Reference in New Issue
Block a user