Introduce internal MP3 support using libsndfile 1.1.0+

This commit is contained in:
Mads Kiilerich 2022-10-13 17:25:53 +02:00 committed by Robin Gareus
parent 886fe364b3
commit 5ff1f28af8
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
5 changed files with 73 additions and 1 deletions

View file

@ -355,6 +355,32 @@ public:
}
};
class LIBARDOUR_API ExportFormatMPEG : public ExportFormat, public HasSampleFormat, public HasCodecQuality
{
public:
ExportFormatMPEG (std::string const& name, std::string const& ext);
~ExportFormatMPEG (){};
bool set_compatibility_state (ExportFormatCompatibility const& compatibility);
Type get_type () const
{
return T_Sndfile;
}
SampleFormat default_sample_format () const
{
return SF_MPEG_LAYER_III;
}
int default_codec_quality () const
{
return 40;
}
virtual bool supports_tagging () const
{
return true;
}
};
class LIBARDOUR_API ExportFormatFFMPEG : public ExportFormat, public HasCodecQuality
{
public:

View file

@ -218,6 +218,11 @@ ExportFormatManager::init_formats ()
if (ArdourVideoToolPaths::transcoder_exe (unused, unused)) {
f_ptr.reset (new ExportFormatFFMPEG ("MP3", "mp3"));
add_format (f_ptr);
} else {
try {
f_ptr.reset (new ExportFormatMPEG ("MP3", "mp3"));
add_format (f_ptr);
} catch (ExportFormatIncompatible & e) {}
}
}

View file

@ -382,6 +382,44 @@ ExportFormatBWF::set_compatibility_state (ExportFormatCompatibility const & comp
}
/*** MPEG / MP3 ***/
ExportFormatMPEG::ExportFormatMPEG (std::string const& name, std::string const& ext) :
HasSampleFormat (sample_formats)
{
SF_INFO sf_info;
sf_info.channels = 2;
sf_info.samplerate = SR_44_1;
sf_info.format = F_MPEG | SF_MPEG_LAYER_III;
if (sf_format_check (&sf_info) != SF_TRUE) {
throw ExportFormatIncompatible();
}
set_name (name);
set_format_id (F_MPEG);
add_sample_format (SF_MPEG_LAYER_III);
add_endianness (E_FileDefault);
// libsndfile doesn't expose direct quality control - use these coarse approximations
add_codec_quality ("Low (0%)", 0);
add_codec_quality ("Default (40%)", 40);
add_codec_quality ("High (60%)", 60);
add_codec_quality ("Very High (100%)", 100);
set_extension (ext);
set_quality (Q_LossyCompression);
}
bool
ExportFormatMPEG::set_compatibility_state (ExportFormatCompatibility const & compatibility)
{
bool compatible = compatibility.has_format (F_MPEG);
set_compatible (compatible);
return compatible;
}
/*** FFMPEG Pipe ***/
ExportFormatFFMPEG::ExportFormatFFMPEG (std::string const& name, std::string const& ext)

View file

@ -344,7 +344,8 @@ ExportGraphBuilder::Encoder::init_writer (boost::shared_ptr<AudioGrapher::Sndfil
writer.reset (new AudioGrapher::SndfileWriter<T> (writer_filename, format, channels, config.format->sample_rate(), config.broadcast_info));
writer->FileWritten.connect_same_thread (copy_files_connection, boost::bind (&ExportGraphBuilder::Encoder::copy_files, this, _1));
if ((format & SF_FORMAT_SUBMASK) == ExportFormatBase::SF_Vorbis) {
if ((format & SF_FORMAT_SUBMASK) == ExportFormatBase::SF_Vorbis ||
(format & SF_FORMAT_TYPEMASK) == ExportFormatBase::F_MPEG) {
/* libsndfile uses range 0..1 (worst.. best) for
* SFC_SET_VBR_ENCODING_QUALITY and maps
* SFC_SET_COMPRESSION_LEVEL = 1.0 - VBR_ENCODING_QUALITY

View file

@ -21,6 +21,7 @@
#include <strings.h>
#include <sndfile.h>
#include "ardour/sndfile_helpers.h"
#include "ardour/export_format_base.h"
using namespace std;
@ -41,6 +42,7 @@ sndfile_data_width (int format)
return 32;
case SF_FORMAT_FLOAT:
case SF_FORMAT_DOUBLE:
case ARDOUR::ExportFormatBase::SF_MPEG_LAYER_III:
return 1; /* ridiculous but used as a magic value */
default:
// we don't handle anything else within ardour