1 #ifndef AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H
2 #define AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H
3 
4 #include "audiographer/visibility.h"
5 #include "audiographer/sink.h"
6 #include "audiographer/utils/listed_source.h"
7 #include "private/gdither/gdither_types.h"
8 
9 namespace AudioGrapher
10 {
11 
12 /// Dither types from the gdither library
13 enum /*LIBAUDIOGRAPHER_API*/ DitherType
14 {
15 	D_None   = GDitherNone,   ///< No didtering
16 	D_Rect   = GDitherRect,   ///< Rectangular dithering, i.e. white noise
17 	D_Tri    = GDitherTri,    ///< Triangular dithering
18 	D_Shaped = GDitherShaped  ///< Actually noise shaping, only works for 46kHzish signals
19 };
20 
21 /** Sample format converter that does dithering.
22   * This class can only convert floats to either \a float, \a int32_t, \a int16_t, or \a uint8_t
23   */
24 template <typename TOut>
25 class LIBAUDIOGRAPHER_API SampleFormatConverter
26   : public Sink<float>
27   , public ListedSource<TOut>
28   , public Throwing<>
29 {
30   public:
31 	/** Constructor
32 	  * \param channels number of channels in stream
33 	  */
34 	SampleFormatConverter (ChannelCount channels);
35 	~SampleFormatConverter ();
36 
37 	/** Initialize and allocate buffers for processing.
38 	  * \param max_samples maximum number of samples that is allowed to be used in calls to \a process()
39 	  * \param type dither type from \a DitherType
40 	  * \param data_width data with in bits
41 	  * \note If the non-const version of process() is used with floats,
42 	  *       there is no need to call this function.
43 	  */
44 	void init (samplecnt_t max_samples, int type, int data_width);
45 
46 	/// Set whether or not clipping to [-1.0, 1.0] should occur when TOut = float. Clipping is off by default
set_clip_floats(bool yn)47 	void set_clip_floats (bool yn) { clip_floats = yn; }
48 
49 	/// Processes data without modifying it
50 	void process (ProcessContext<float> const & c_in);
51 
52 	/// This version is only different in the case when \a TOut = float, and float clipping is on.
53 	void process (ProcessContext<float> & c_in);
54 
55   private:
56 	void reset();
57 	void init_common (samplecnt_t max_samples); // not-template-specialized part of init
58 	void check_sample_and_channel_count (samplecnt_t samples, ChannelCount channels_);
59 
60 	ChannelCount channels;
61 	GDither      dither;
62 	samplecnt_t   data_out_size;
63 	TOut *       data_out;
64 
65 	bool         clip_floats;
66 
67 };
68 
69 } // namespace
70 
71 #endif // AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H
72