visibility macros and flush() added to SrcFileSource; merge with master
[ardour.git] / libs / audiographer / src / general / sample_format_converter.cc
index a1aa4d88a9bb515fd34dd065c9393e6fa90d7fcc..aaeda094774efd7d8ac7dc32b8a521c58e66e27b 100644 (file)
@@ -1,3 +1,23 @@
+/*
+    Copyright (C) 2012 Paul Davis 
+    Author: Sakari Bergen
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include "audiographer/general/sample_format_converter.h"
 
 #include "audiographer/exception.h"
@@ -34,27 +54,26 @@ template <>
 void
 SampleFormatConverter<int32_t>::init (framecnt_t max_frames, int type, int data_width)
 {
-       if(throw_level (ThrowObject) && data_width < 24) {
-               throw Exception (*this, "Trying to use SampleFormatConverter<int32_t> for data widths < 24");
+       if(throw_level (ThrowObject) && data_width > 32) {
+               throw Exception (*this, "Trying to use SampleFormatConverter<int32_t> with a data width > 32");
        }
-       
+
+       // GDither is broken with GDither32bit if the dither depth is bigger than 24.
+       // And since floats only have 24 bits of data, we are fine with this.
+       data_width = std::min(data_width, 24);
+
        init_common (max_frames);
-       
-       if (data_width == 24) {
-               dither = gdither_new ((GDitherType) type, channels, GDither32bit, data_width);
-       } else if (data_width == 32) {
-               dither = gdither_new (GDitherNone, channels, GDitherFloat, data_width);
-       } else if (throw_level (ThrowObject)) {
-               throw Exception (*this, "Unsupported data width");
-       }
+       dither = gdither_new ((GDitherType) type, channels, GDither32bit, data_width);
 }
 
 template <>
 void
 SampleFormatConverter<int16_t>::init (framecnt_t max_frames, int type, int data_width)
 {
-       if (throw_level (ThrowObject) && data_width != 16) {
-               throw Exception (*this, "Unsupported data width");
+       if (throw_level (ThrowObject) && data_width > 16) {
+               throw Exception (*this, boost::str(boost::format
+                   ("Data width (%1%) too large for int16_t")
+                   % data_width));
        }
        init_common (max_frames);
        dither = gdither_new ((GDitherType) type, channels, GDither16bit, data_width);
@@ -64,8 +83,10 @@ template <>
 void
 SampleFormatConverter<uint8_t>::init (framecnt_t max_frames, int type, int data_width)
 {
-       if (throw_level (ThrowObject) && data_width != 8) {
-               throw Exception (*this, "Unsupported data width");
+       if (throw_level (ThrowObject) && data_width > 8) {
+               throw Exception (*this, boost::str(boost::format
+                   ("Data width (%1%) too large for uint8_t")
+                   % data_width));
        }
        init_common (max_frames);
        dither = gdither_new ((GDitherType) type, channels, GDither8bit, data_width);
@@ -125,7 +146,7 @@ SampleFormatConverter<TOut>::process (ProcessContext<float> const & c_in)
        /* Write forward */
 
        ProcessContext<TOut> c_out(c_in, data_out);
-       output (c_out);
+       this->output (c_out);
 }
 
 /* Basic non-const version of process(), calls the const one */