cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

Effects_Buffer.h (3791B)


      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
     11class Effects_Buffer : public Multi_Buffer {
     12public:
     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, long echo_size = 24 * 1024L );
     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	};
     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	};
     51	chan_config_t& chan_config( int i ) { return chans [i + extra_chans].cfg; }
     52
     53	// Apply any changes made to config() and chan_config()
     54	virtual void apply_config();
     55
     56public:
     57	~Effects_Buffer();
     58	blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
     59	blargg_err_t set_channel_count( int, int const* = 0 );
     60	void clock_rate( long );
     61	void bass_freq( int );
     62	void clear();
     63	channel_t channel( int );
     64	void end_frame( blip_time_t );
     65	long read_samples( blip_sample_t*, long );
     66	long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
     67	enum { stereo = 2 };
     68	typedef blargg_long fixed_t;
     69protected:
     70	enum { extra_chans = stereo * stereo };
     71private:
     72	config_t config_;
     73	long clock_rate_;
     74	int bass_freq_;
     75
     76	blargg_long echo_size;
     77
     78	struct chan_t
     79	{
     80		fixed_t vol [stereo];
     81		chan_config_t cfg;
     82		channel_t channel;
     83	};
     84	blargg_vector<chan_t> chans;
     85
     86	struct buf_t : Tracked_Blip_Buffer
     87	{
     88		fixed_t vol [stereo];
     89		bool echo;
     90
     91		void* operator new ( size_t, void* p ) { return p; }
     92		void operator delete ( void* ) { }
     93
     94		~buf_t() { }
     95	};
     96	buf_t* bufs;
     97	int bufs_size;
     98	int bufs_max; // bufs_size <= bufs_max, to limit memory usage
     99	Stereo_Mixer mixer;
    100
    101	struct {
    102		long delay [stereo];
    103		fixed_t treble;
    104		fixed_t feedback;
    105		fixed_t low_pass [stereo];
    106	} s;
    107
    108	blargg_vector<fixed_t> echo;
    109	blargg_long echo_pos;
    110
    111	bool no_effects;
    112	bool no_echo;
    113
    114	void assign_buffers();
    115	void clear_echo();
    116	void mix_effects( blip_sample_t* out, int pair_count );
    117	blargg_err_t new_bufs( int size );
    118	void delete_bufs();
    119};
    120
    121// Simpler interface and lower memory usage
    122class Simple_Effects_Buffer : public Effects_Buffer {
    123public:
    124	struct config_t
    125	{
    126		bool enabled;   // false = disable all effects
    127		float echo;     // 0.0 = none, 1.0 = lots
    128		float stereo;   // 0.0 = channels in center, 1.0 = channels on left/right
    129		bool surround;  // true = put some channels in back
    130	};
    131	config_t& config() { return config_; }
    132
    133	// Apply any changes made to config()
    134	void apply_config();
    135
    136public:
    137	Simple_Effects_Buffer();
    138private:
    139	config_t config_;
    140	void chan_config(); // hide
    141};
    142
    143#endif