1 // Common interface for resamplers
2 
3 // $package
4 #ifndef RESAMPLER_H
5 #define RESAMPLER_H
6 
7 #include "blargg_common.h"
8 
9 class Resampler {
10 public:
11 
12 	virtual ~Resampler();
13 
14 	// Sets input/output resampling ratio
15 	blargg_err_t set_rate( double );
16 
17 	// Current input/output ratio
rate()18 	double rate() const             { return rate_; }
19 
20 	// Samples are 16-bit signed
21 	typedef short sample_t;
22 
23 // One of two different buffering schemes can be used, as decided by the caller:
24 
25 // External buffering (caller provides input buffer)
26 
27 	// Resamples in to at most n out samples and returns number of samples actually
28 	// written. Sets *in_size to number of input samples that aren't needed anymore
29 	// and should be removed from input.
30 	int resample( sample_t out [], int n, sample_t const in [], int* in_size );
31 
32 // Internal buffering (resampler manages buffer)
33 
34 	// Resizes input buffer to n samples, then clears it
35 	blargg_err_t resize_buffer( int n );
36 
37 	// Clears input buffer
38 	void clear();
39 
40 	// Writes at most n samples to input buffer and returns number actually written.
41 	// Result will be less than n if there isn't enough free space in buffer.
42 	int write( sample_t const in [], int n );
43 
44 	// Number of input samples in buffer
written()45 	int written() const             { return write_pos; }
46 
47 	// Removes first n input samples from buffer, fewer if there aren't that many.
48 	// Returns number of samples actually removed.
49 	int skip_input( int n );
50 
51 	// Resamples input to at most n output samples. Returns number of samples
52 	// actually written to out. Result will be less than n if there aren't
53 	// enough input samples in buffer.
54 	int read( sample_t out [], int n );
55 
56 // Direct writing to input buffer, instead of using write( in, n ) above
57 
58 	// Pointer to place to write input samples
buffer()59 	sample_t* buffer()              { return &buf [write_pos]; }
60 
61 	// Number of samples that can be written to buffer()
buffer_free()62 	int buffer_free() const         { return buf.size() - write_pos; }
63 
64 	// Notifies resampler that n input samples have been written to buffer().
65 	// N must not be greater than buffer_free().
66 	void write( int n );
67 
68 // Derived interface
69 protected:
set_rate_(double rate)70 	virtual blargg_err_t set_rate_( double rate ) BLARGG_PURE( ; )
71 
72 	virtual void clear_() { }
73 
74 	// Resample as many available in samples as will fit within out_size and
75 	// return pointer past last input sample read and set *out just past
76 	// the last output sample.
77 	virtual sample_t const* resample_( sample_t** out, sample_t const* out_end,
78 			sample_t const in [], int in_size ) BLARGG_PURE( { return in; } )
79 
80 // Implementation
81 public:
82 	Resampler();
83 
84 private:
85 	blargg_vector<sample_t> buf;
86 	int write_pos;
87 	double rate_;
88 
89 	int resample_wrapper( sample_t out [], int* out_size,
90 			sample_t const in [], int in_size );
91 };
92 
write(int count)93 inline void Resampler::write( int count )
94 {
95 	write_pos += count;
96 	assert( (unsigned) write_pos <= buf.size() );
97 }
98 
set_rate_(double r)99 inline blargg_err_t Resampler::set_rate_( double r )
100 {
101 	rate_ = r;
102 	return blargg_ok;
103 }
104 
set_rate(double r)105 inline blargg_err_t Resampler::set_rate( double r )
106 {
107 	return set_rate_( r );
108 }
109 
110 #endif
111