From 70f31c89a3dca4a3a6dda92819b4acb2b2ccb390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Wed, 5 Jul 2023 00:12:08 +0200 Subject: [PATCH] aconv: Support FLAC encoding The main write loop is refactored so that adding further formats via the new Encoder interface should be much simpler. --- Base/usr/share/man/man1/aconv.md | 2 +- Userland/Utilities/aconv.cpp | 34 ++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Base/usr/share/man/man1/aconv.md b/Base/usr/share/man/man1/aconv.md index f42e25b7b1..62ac45bc46 100644 --- a/Base/usr/share/man/man1/aconv.md +++ b/Base/usr/share/man/man1/aconv.md @@ -26,7 +26,7 @@ Note that `aconv` currently only supports codecs which have their own bespoke co * `mp3` (decode): MPEG Layer III audio codec and container. * `wav` (decode, encode): RIFF WAVE audio codec and container. Supports sample formats `u8` and `s16le` for writing. -* `flac` (decode): Free Lossless Audio Codec and container. +* `flac` (decode, encode): Free Lossless Audio Codec and container. Supports all integer sample formats for writing. * `qoa` (decode): Quite Okay Audio codec and container. ### Supported Sample Formats diff --git a/Userland/Utilities/aconv.cpp b/Userland/Utilities/aconv.cpp index 1d170119a6..948b9256f0 100644 --- a/Userland/Utilities/aconv.cpp +++ b/Userland/Utilities/aconv.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -90,7 +92,7 @@ ErrorOr serenity_main(Main::Arguments arguments) if (input_format.is_empty()) { auto loader_or_error = Audio::Loader::create(input); if (loader_or_error.is_error()) { - warnln("Could not guess codec for input file '{}'. Try forcing a codec with '--i:c:a'", input); + warnln("Could not guess codec for input file '{}'. Try forcing a codec with '--input-audio-codec'", input); return 1; } input_loader = loader_or_error.release_value(); @@ -104,9 +106,9 @@ ErrorOr serenity_main(Main::Arguments arguments) output_format = TRY(guess_format_from_extension(output)); VERIFY(!output_format.is_empty()); - if (output_format == "wav"sv) { - Optional> writer; - if (!output.is_empty()) { + Optional> writer; + if (!output.is_empty()) { + if (output_format == "wav"sv) { auto parsed_output_sample_format = input_loader->pcm_format(); if (!output_sample_format.is_empty()) parsed_output_sample_format = TRY(parse_sample_format(output_sample_format)); @@ -116,7 +118,29 @@ ErrorOr serenity_main(Main::Arguments arguments) static_cast(input_loader->sample_rate()), input_loader->num_channels(), parsed_output_sample_format))); + } else if (output_format == "flac"sv) { + auto parsed_output_sample_format = input_loader->pcm_format(); + if (!output_sample_format.is_empty()) + parsed_output_sample_format = TRY(parse_sample_format(output_sample_format)); + + if (!Audio::is_integer_format(parsed_output_sample_format)) { + warnln("FLAC does not support sample format {}", Audio::sample_format_name(parsed_output_sample_format)); + return 1; + } + + auto output_stream = TRY(Core::OutputBufferedFile::create(TRY(Core::File::open(output, Core::File::OpenMode::Write | Core::File::OpenMode::Truncate)))); + auto flac_writer = TRY(Audio::FlacWriter::create( + move(output_stream), + static_cast(input_loader->sample_rate()), + input_loader->num_channels(), + Audio::pcm_bits_per_sample(parsed_output_sample_format))); + TRY(flac_writer->finalize_header_format()); + writer.emplace(move(flac_writer)); + } else { + warnln("Codec {} is not supported for encoding", output_format); + return 1; } + if (output != "-"sv) out("Writing: \033[s"); @@ -140,8 +164,6 @@ ErrorOr serenity_main(Main::Arguments arguments) TRY((*writer)->finalize()); if (output != "-"sv) outln(); - } else { - warnln("Codec {} is not supported for encoding", output_format); } return 0;