1 // Multi-channel effects buffer with echo and individual panning for each channel 2 3 // Game_Music_Emu $vers 4 #ifndef EFFECTS_BUFFER_H 5 #define EFFECTS_BUFFER_H 6 7 #include "Multi_Buffer.h" 8 9 // See Simple_Effects_Buffer (below) for a simpler interface 10 11 class Effects_Buffer : public Multi_Buffer { 12 public: 13 // To reduce memory usage, fewer buffers can be used (with a best-fit 14 // approach if there are too few), and maximum echo delay can be reduced 15 Effects_Buffer( int max_bufs = 32, int echo_size = 24 * 1024 ); 16 17 struct pan_vol_t 18 { 19 float vol; // 0.0 = silent, 0.5 = half volume, 1.0 = normal 20 float pan; // -1.0 = left, 0.0 = center, +1.0 = right 21 }; 22 23 // Global configuration 24 struct config_t 25 { 26 bool enabled; // false = disable all effects 27 28 // Current sound is echoed at adjustable left/right delay, 29 // with reduced treble and volume (feedback). 30 float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent 31 int delay [2]; // left, right delays (msec) 32 float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony 33 pan_vol_t side_chans [2]; // left and right side channel volume and pan 34 }; config()35 config_t& config() { return config_; } 36 37 // Limits of delay (msec) 38 int min_delay() const; 39 int max_delay() const; 40 41 // Per-channel configuration. Two or more channels with matching parameters are 42 // optimized to internally use the same buffer. 43 struct chan_config_t : pan_vol_t 44 { 45 // (inherited from pan_vol_t) 46 //float vol; // these only affect center channel 47 //float pan; 48 bool surround; // if true, negates left volume to put sound in back 49 bool echo; // false = channel doesn't have any echo 50 }; chan_config(int i)51 chan_config_t& chan_config( int i ) { return chans [i + extra_chans].cfg; } 52 53 // Applies any changes made to config() and chan_config() 54 virtual void apply_config(); 55 56 // Implementation 57 public: 58 ~Effects_Buffer(); 59 blargg_err_t set_sample_rate( int samples_per_sec, int msec = blip_default_length ); 60 blargg_err_t set_channel_count( int, int const* = NULL ); 61 void clock_rate( int ); 62 void bass_freq( int ); 63 void clear(); 64 channel_t channel( int ); 65 void end_frame( blip_time_t ); 66 int read_samples( blip_sample_t [], int ); samples_avail()67 int samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; } 68 enum { stereo = 2 }; 69 typedef int fixed_t; 70 71 protected: 72 enum { extra_chans = stereo * stereo }; 73 74 private: 75 config_t config_; 76 int clock_rate_; 77 int bass_freq_; 78 79 int echo_size; 80 81 struct chan_t 82 { 83 fixed_t vol [stereo]; 84 chan_config_t cfg; 85 channel_t channel; 86 }; 87 blargg_vector<chan_t> chans; 88 89 struct buf_t : Tracked_Blip_Buffer 90 { 91 // nasty: Blip_Buffer has something called fixed_t 92 Effects_Buffer::fixed_t vol [stereo]; 93 bool echo; 94 newbuf_t95 void* operator new ( size_t, void* p ) { return p; } deletebuf_t96 void operator delete ( void* ) { } 97 ~buf_tbuf_t98 ~buf_t() { } 99 }; 100 buf_t* bufs; 101 int bufs_size; 102 int bufs_max; // bufs_size <= bufs_max, to limit memory usage 103 Stereo_Mixer mixer; 104 105 struct { 106 int delay [stereo]; 107 fixed_t treble; 108 fixed_t feedback; 109 fixed_t low_pass [stereo]; 110 } s; 111 112 blargg_vector<fixed_t> echo; 113 int echo_pos; 114 115 bool no_effects; 116 bool no_echo; 117 118 void assign_buffers(); 119 void clear_echo(); 120 void mix_effects( blip_sample_t out [], int pair_count ); 121 blargg_err_t new_bufs( int size ); 122 void delete_bufs(); 123 }; 124 125 // Simpler interface and lower memory usage 126 class Simple_Effects_Buffer : public Effects_Buffer { 127 public: 128 struct config_t 129 { 130 bool enabled; // false = disable all effects 131 132 float echo; // 0.0 = none, 1.0 = lots 133 float stereo; // 0.0 = channels in center, 1.0 = channels on left/right 134 bool surround; // true = put some channels in back 135 }; config()136 config_t& config() { return config_; } 137 138 // Applies any changes made to config() 139 void apply_config(); 140 141 // Implementation 142 public: 143 Simple_Effects_Buffer(); 144 private: 145 config_t config_; 146 void chan_config(); // hide 147 }; 148 149 #endif 150