Implement vorbis encoder quality
authorRobin Gareus <robin@gareus.org>
Tue, 20 Nov 2018 02:21:17 +0000 (03:21 +0100)
committerRobin Gareus <robin@gareus.org>
Tue, 20 Nov 2018 02:21:17 +0000 (03:21 +0100)
This also prepares for codec-quality defaults, but
ExportFormatSpecification does not yet set those for previously unset
or new formats/presets.

libs/ardour/ardour/export_formats.h
libs/ardour/export_formats.cc
libs/ardour/export_graph_builder.cc

index b8ce3db96af7486fafcce0587702c2eb58b1c57a..fc419d47ce1810e18dacfb227c3c35e0c0263983 100644 (file)
@@ -88,7 +88,7 @@ class LIBARDOUR_API ExportFormat : public ExportFormatBase, public ExportFormatB
        void set_quality (Quality value) { qualities.clear(); qualities.insert (value); }
 };
 
-class LIBARDOUR_API HasCodecQuality : public PBD::ScopedConnectionList {
+class LIBARDOUR_API HasCodecQuality {
 public:
        struct CodecQuality {
                CodecQuality (std::string const& n, int q)
@@ -114,6 +114,8 @@ public:
                return _codec_qualties;
        }
 
+       virtual int default_codec_quality () const = 0;
+
 protected:
        CodecQualityList _codec_qualties;
 };
@@ -207,7 +209,7 @@ class LIBARDOUR_API ExportFormatLinear : public ExportFormat, public HasSampleFo
        SampleFormat _default_sample_format;
 };
 
-class LIBARDOUR_API ExportFormatOggVorbis : public ExportFormat {
+class LIBARDOUR_API ExportFormatOggVorbis : public ExportFormat, public HasCodecQuality {
   public:
        ExportFormatOggVorbis ();
        ~ExportFormatOggVorbis () {};
@@ -216,6 +218,8 @@ class LIBARDOUR_API ExportFormatOggVorbis : public ExportFormat {
        Type get_type () const { return T_Sndfile; }
        SampleFormat get_explicit_sample_format () const { return SF_Vorbis; }
        virtual bool supports_tagging () const { return true; }
+
+       int default_codec_quality () const { return 40; }
 };
 
 class LIBARDOUR_API ExportFormatFLAC : public ExportFormat, public HasSampleFormat {
@@ -252,6 +256,7 @@ class LIBARDOUR_API ExportFormatFFMPEG : public ExportFormat, public HasCodecQua
        bool set_compatibility_state (ExportFormatCompatibility const & compatibility);
        Type get_type () const { return T_FFMPEG; }
        SampleFormat get_explicit_sample_format () const { return SF_Float; }
+       int default_codec_quality () const { return -2; }
 };
 
 } // namespace ARDOUR
index 2539502f92b8bfffee923c83f63d2ece8e7af3e6..718dcd81c65bb30789fc9056349847bbc91f3b43 100644 (file)
@@ -275,6 +275,12 @@ ExportFormatOggVorbis::ExportFormatOggVorbis ()
        add_sample_rate (SR_192);
        add_sample_rate (SR_Session);
 
+       /* these are 100 vorbis_encode_init_vbr() quality */
+       add_codec_quality ("Low (0)",           0);
+       add_codec_quality ("Default (4)",      40);
+       add_codec_quality ("High (6)",         60);
+       add_codec_quality ("Very High (10)",  100);
+
        add_endianness (E_FileDefault);
 
        set_extension ("ogg");
index e190791291b8f5288fae3c2214760b5b15d26f36..c09e00219d7e2a6f7f600133e7570a5cf3a48bc4 100644 (file)
@@ -305,6 +305,13 @@ 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 & ExportFormatBase::SF_Vorbis) {
+               /* libsndfile uses range 0..1 (best .. worst) */
+               double vorbis_quality = 1.0 - config.format->codec_quality () / 100.f;
+               if (vorbis_quality >= 0 && vorbis_quality <= 1.0) {
+                       writer->command (SFC_SET_COMPRESSION_LEVEL, &vorbis_quality, sizeof (double));
+               }
+       }
 }
 
 template<typename T>