1 // Band-limited sound synthesis buffer
2 
3 // Blip_Buffer $vers
4 #ifndef BLIP_BUFFER_H
5 #define BLIP_BUFFER_H
6 
7 #include "blargg_common.h"
8 #include "Blip_Buffer_impl.h"
9 
10 typedef int blip_time_t;                    // Source clocks in current time frame
11 typedef BOOST::int16_t blip_sample_t;       // 16-bit signed output sample
12 int const blip_default_length = 1000 / 4;   // Default Blip_Buffer length (1/4 second)
13 
14 
15 //// Sample buffer for band-limited synthesis
16 
17 class Blip_Buffer : public Blip_Buffer_ {
18 public:
19 
20 	// Sets output sample rate and resizes and clears sample buffer
21 	blargg_err_t set_sample_rate( int samples_per_sec, int msec_length = blip_default_length );
22 
23 	// Sets number of source time units per second
24 	void clock_rate( int clocks_per_sec );
25 
26 	// Clears buffer and removes all samples
27 	void clear();
28 
29 	// Use Blip_Synth to add waveform to buffer
30 
31 	// Resamples to time t, then subtracts t from current time. Appends result of resampling
32 	// to buffer for reading.
33 	void end_frame( blip_time_t t );
34 
35 	// Number of samples available for reading with read_samples()
36 	int samples_avail() const;
37 
38 	// Reads at most n samples to out [0 to n-1] and returns number actually read. If stereo
39 	// is true, writes to out [0], out [2], out [4] etc. instead.
40 	int read_samples( blip_sample_t out [], int n, bool stereo = false );
41 
42 // More features
43 
44 	// Sets flag that tells some Multi_Buffer types that sound was added to buffer,
45 	// so they know that it needs to be mixed in. Only needs to be called once
46 	// per time frame that sound was added. Not needed if not using Multi_Buffer.
set_modified()47 	void set_modified()                 { modified_ = true; }
48 
49 	// Sets high-pass filter frequency, from 0 to 20000 Hz, where higher values reduce bass more
50 	void bass_freq( int frequency );
51 
52 	int length() const;         // Length of buffer in milliseconds
53 	int sample_rate() const;    // Current output sample rate
54 	int clock_rate() const;     // Number of source time units per second
55 	int output_latency() const; // Number of samples delay from offset() to read_samples()
56 
57 // Low-level features
58 
59 	// Removes the first n samples
60 	void remove_samples( int n );
61 
62 	// Returns number of clocks needed until n samples will be available.
63 	// If buffer cannot even hold n samples, returns number of clocks
64 	// until buffer becomes full.
65 	blip_time_t count_clocks( int n ) const;
66 
67 	// Number of samples that should be mixed before calling end_frame( t )
68 	int count_samples( blip_time_t t ) const;
69 
70 	// Mixes n samples into buffer
71 	void mix_samples( const blip_sample_t in [], int n );
72 
73 // Resampled time (sorry, poor documentation right now)
74 
75 	// Resampled time is fixed-point, in terms of output samples.
76 
77 	// Converts clock count to resampled time
resampled_duration(int t)78 	blip_resampled_time_t resampled_duration( int t ) const         { return t * factor_; }
79 
80 	// Converts clock time since beginning of current time frame to resampled time
resampled_time(blip_time_t t)81 	blip_resampled_time_t resampled_time( blip_time_t t ) const     { return t * factor_ + offset_; }
82 
83 	// Returns factor that converts clock rate to resampled time
84 	blip_resampled_time_t clock_rate_factor( int clock_rate ) const;
85 
86 // State save/load
87 
88 	// Saves state, including high-pass filter and tails of last deltas.
89 	// All samples must have been read from buffer before calling this
90 	// (that is, samples_avail() must return 0).
91 	void save_state( blip_buffer_state_t* out );
92 
93 	// Loads state. State must have been saved from Blip_Buffer with same
94 	// settings during same run of program; states can NOT be stored on disk.
95 	// Clears buffer before loading state.
96 	void load_state( const blip_buffer_state_t& in );
97 
98 private:
99 	// noncopyable
100 	Blip_Buffer( const Blip_Buffer& );
101 	Blip_Buffer& operator = ( const Blip_Buffer& );
102 
103 // Implementation
104 public:
105 	BLARGG_DISABLE_NOTHROW
106 	Blip_Buffer();
107 	~Blip_Buffer();
108 	void remove_silence( int n );
109 };
110 
111 
112 //// Adds amplitude changes to Blip_Buffer
113 
114 template<int quality,int range> class Blip_Synth;
115 
116 typedef Blip_Synth<8, 1> Blip_Synth_Fast; // faster, but less equalizer control
117 typedef Blip_Synth<12,1> Blip_Synth_Norm; // good for most things
118 typedef Blip_Synth<16,1> Blip_Synth_Good; // sharper filter cutoff
119 
120 template<int quality,int range>
121 class Blip_Synth {
122 public:
123 
124 	// Sets volume of amplitude delta unit
volume(double v)125 	void volume( double v )                     { impl.volume_unit( 1.0 / range * v ); }
126 
127 	// Configures low-pass filter
treble_eq(const blip_eq_t & eq)128 	void treble_eq( const blip_eq_t& eq )       { impl.treble_eq( eq ); }
129 
130 	// Gets/sets default Blip_Buffer
output()131 	Blip_Buffer* output() const                 { return impl.buf; }
output(Blip_Buffer * b)132 	void output( Blip_Buffer* b )               { impl.buf = b; impl.last_amp = 0; }
133 
134 	// Extends waveform to time t at current amplitude, then changes its amplitude to a
135 	// Using this requires a separate Blip_Synth for each waveform.
136 	void update( blip_time_t t, int a );
137 
138 // Low-level interface
139 
140 	// If no Blip_Buffer* is specified, uses one set by output() above
141 
142 	// Adds amplitude transition at time t. Delta can be positive or negative.
143 	// The actual change in amplitude is delta * volume.
144 	void offset( blip_time_t t, int delta, Blip_Buffer* ) const;
offset(blip_time_t t,int delta)145 	void offset( blip_time_t t, int delta               ) const { offset( t, delta, impl.buf ); }
146 
147 	// Same as offset(), except code is inlined for higher performance
offset_inline(blip_time_t t,int delta,Blip_Buffer * buf)148 	void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { offset_resampled( buf->to_fixed( t ), delta, buf ); }
offset_inline(blip_time_t t,int delta)149 	void offset_inline( blip_time_t t, int delta                   ) const { offset_resampled( impl.buf->to_fixed( t ), delta, impl.buf ); }
150 
151 	// Works directly in terms of fractional output samples. Use resampled time functions in Blip_Buffer
152 	// to convert clock counts to resampled time.
153 	void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
154 
155 // Implementation
156 public:
157 	BLARGG_DISABLE_NOTHROW
158 
159 private:
160 #if BLIP_BUFFER_FAST
161 	Blip_Synth_Fast_ impl;
162 	typedef char coeff_t;
163 #else
164 	Blip_Synth_ impl;
165 	typedef short coeff_t;
166 	// Left halves of first difference of step response for each possible phase
167 	coeff_t phases [quality / 2 * blip_res];
168 public:
169 	Blip_Synth() : impl( phases, quality ) { }
170 #endif
171 };
172 
173 
174 //// Low-pass equalization parameters
175 
176 class blip_eq_t {
177 	double treble, kaiser;
178 	int rolloff_freq, sample_rate, cutoff_freq;
179 public:
180 	// Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
181 	// treble, small positive values (0 to 5.0) increase treble.
182 	blip_eq_t( double treble_db = 0 );
183 
184 	// See blip_buffer.txt
185 	blip_eq_t( double treble, int rolloff_freq, int sample_rate, int cutoff_freq = 0,
186 			double kaiser = 5.2 );
187 
188 	// Generate center point and right half of impulse response
189 	virtual void generate( float out [], int count ) const;
~blip_eq_t()190 	virtual ~blip_eq_t() { }
191 
192 	enum { oversample = blip_res };
calc_count(int quality)193 	static int calc_count( int quality ) { return (quality - 1) * (oversample / 2) + 1; }
194 };
195 
196 #include "Blip_Buffer_impl2.h"
197 
198 #endif
199