summaryrefslogtreecommitdiff
path: root/libs/audiographer/audiographer/sample_format_converter.h
blob: 12976ffdd29bd06534385e990ff9bb14943f8174 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H
#define AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H

#include "listed_source.h"
#include "sink.h"
#include "gdither/gdither_types.h"

namespace AudioGrapher
{

/// Dither types from the gdither library
enum DitherType
{
	D_None   = GDitherNone,   ///< No didtering
	D_Rect   = GDitherRect,   ///< Rectangular dithering, i.e. white noise
	D_Tri    = GDitherTri,    ///< Triangular dithering
	D_Shaped = GDitherShaped  ///< Actually noise shaping, only works for 46kHzish signals
};
	
/** Sample format converter that does dithering.
  * This class can only convert floats to either \a float, \a int32_t, \a int16_t, or \a uint8_t 
  */
template <typename TOut>
class SampleFormatConverter : public Sink<float>, public ListedSource<TOut>
{
  public:
	/** Constructor
	  * \param channels number of channels in stream
	  */
	SampleFormatConverter (uint32_t channels);
	~SampleFormatConverter ();
	
	/** Initialize and allocate buffers for processing.
	  * \param max_frames maximum number of frames that is allowed to be used in calls to \a process()
	  * \param type dither type from \a DitherType
	  * \param data_width data with in bits
	  * \note If the non-const version of process() is used with floats,
	  *       there is no need to call this function.
	  */
	void init (nframes_t max_frames, int type, int data_width);

	/// Set whether or not clipping to [-1.0, 1.0] should occur when TOut = float. Clipping is off by default
	void set_clip_floats (bool yn) { clip_floats = yn; }
	
	/// Processes data without modifying it
	void process (ProcessContext<float> const & c_in);
	
	/// This version is only different in the case when \a TOut = float, and float clipping is on.
	void process (ProcessContext<float> & c_in);

  private:
	void reset();
	void init_common(nframes_t max_frames); // not-template-specialized part of init
	void check_frame_count(nframes_t frames);

	uint32_t     channels;
	GDither      dither;
	nframes_t    data_out_size;
	TOut *       data_out;

	bool         clip_floats;

};

} // namespace

#endif // AUDIOGRAPHER_SAMPLE_FORMAT_CONVERTER_H