Multi_Buffer.h (6009B)
1// Multi-channel sound buffer interface, and basic mono and stereo buffers 2 3// Blip_Buffer 0.4.1 4#ifndef MULTI_BUFFER_H 5#define MULTI_BUFFER_H 6 7#include "blargg_common.h" 8#include "Blip_Buffer.h" 9 10// Interface to one or more Blip_Buffers mapped to one or more channels 11// consisting of left, center, and right buffers. 12class Multi_Buffer { 13public: 14 Multi_Buffer( int samples_per_frame ); 15 virtual ~Multi_Buffer() { } 16 17 // Sets the number of channels available and optionally their types 18 // (type information used by Effects_Buffer) 19 enum { type_index_mask = 0xFF }; 20 enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type }; 21 virtual blargg_err_t set_channel_count( int, int const* types = 0 ); 22 int channel_count() const { return channel_count_; } 23 24 // Gets indexed channel, from 0 to channel count - 1 25 struct channel_t { 26 Blip_Buffer* center; 27 Blip_Buffer* left; 28 Blip_Buffer* right; 29 }; 30 virtual channel_t channel( int index ) BLARGG_PURE( ; ) 31 32 // See Blip_Buffer.h 33 virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) BLARGG_PURE( ; ) 34 virtual void clock_rate( long ) BLARGG_PURE( { } ) 35 virtual void bass_freq( int ) BLARGG_PURE( { } ) 36 virtual void clear() BLARGG_PURE( { } ) 37 long sample_rate() const; 38 39 // Length of buffer, in milliseconds 40 int length() const; 41 42 // See Blip_Buffer.h 43 virtual void end_frame( blip_time_t ) BLARGG_PURE( { } ) 44 45 // Number of samples per output frame (1 = mono, 2 = stereo) 46 int samples_per_frame() const; 47 48 // Count of changes to channel configuration. Incremented whenever 49 // a change is made to any of the Blip_Buffers for any channel. 50 unsigned channels_changed_count() { return channels_changed_count_; } 51 52 // See Blip_Buffer.h 53 virtual long read_samples( blip_sample_t*, long ) BLARGG_PURE( { return 0; } ) 54 virtual long samples_avail() const BLARGG_PURE( { return 0; } ) 55 56public: 57 BLARGG_DISABLE_NOTHROW 58 void disable_immediate_removal() { immediate_removal_ = false; } 59protected: 60 bool immediate_removal() const { return immediate_removal_; } 61 int const* channel_types() const { return channel_types_; } 62 void channels_changed() { channels_changed_count_++; } 63private: 64 // noncopyable 65 Multi_Buffer( const Multi_Buffer& ); 66 Multi_Buffer& operator = ( const Multi_Buffer& ); 67 68 unsigned channels_changed_count_; 69 long sample_rate_; 70 int length_; 71 int channel_count_; 72 int const samples_per_frame_; 73 int const* channel_types_; 74 bool immediate_removal_; 75}; 76 77// Uses a single buffer and outputs mono samples. 78class Mono_Buffer : public Multi_Buffer { 79 Blip_Buffer buf; 80 channel_t chan; 81public: 82 // Buffer used for all channels 83 Blip_Buffer* center() { return &buf; } 84 85public: 86 Mono_Buffer(); 87 ~Mono_Buffer(); 88 blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ); 89 void clock_rate( long rate ) { buf.clock_rate( rate ); } 90 void bass_freq( int freq ) { buf.bass_freq( freq ); } 91 void clear() { buf.clear(); } 92 long samples_avail() const { return buf.samples_avail(); } 93 long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); } 94 channel_t channel( int ) { return chan; } 95 void end_frame( blip_time_t t ) { buf.end_frame( t ); } 96}; 97 98 class Tracked_Blip_Buffer : public Blip_Buffer { 99 public: 100 // Non-zero if buffer still has non-silent samples in it. Requires that you call 101 // set_modified() appropriately. 102 blip_ulong non_silent() const; 103 104 // remove_samples( samples_avail() ) 105 void remove_all_samples(); 106 107 public: 108 BLARGG_DISABLE_NOTHROW 109 110 long read_samples( blip_sample_t*, long ); 111 void remove_silence( long ); 112 void remove_samples( long ); 113 Tracked_Blip_Buffer(); 114 void clear(); 115 void end_frame( blip_time_t ); 116 private: 117 blip_long last_non_silence; 118 void remove_( long ); 119 }; 120 121 class Stereo_Mixer { 122 public: 123 Tracked_Blip_Buffer* bufs [3]; 124 blargg_long samples_read; 125 126 Stereo_Mixer() : samples_read( 0 ) { } 127 void read_pairs( blip_sample_t* out, int count ); 128 private: 129 void mix_mono ( blip_sample_t* out, int pair_count ); 130 void mix_stereo( blip_sample_t* out, int pair_count ); 131 }; 132 133// Uses three buffers (one for center) and outputs stereo sample pairs. 134class Stereo_Buffer : public Multi_Buffer { 135public: 136 137 // Buffers used for all channels 138 Blip_Buffer* center() { return &bufs [2]; } 139 Blip_Buffer* left() { return &bufs [0]; } 140 Blip_Buffer* right() { return &bufs [1]; } 141 142public: 143 Stereo_Buffer(); 144 ~Stereo_Buffer(); 145 blargg_err_t set_sample_rate( long, int msec = blip_default_length ); 146 void clock_rate( long ); 147 void bass_freq( int ); 148 void clear(); 149 channel_t channel( int ) { return chan; } 150 void end_frame( blip_time_t ); 151 152 long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; } 153 long read_samples( blip_sample_t*, long ); 154 155private: 156 enum { bufs_size = 3 }; 157 typedef Tracked_Blip_Buffer buf_t; 158 buf_t bufs [bufs_size]; 159 Stereo_Mixer mixer; 160 channel_t chan; 161}; 162 163// Silent_Buffer generates no samples, useful where no sound is wanted 164class Silent_Buffer : public Multi_Buffer { 165 channel_t chan; 166public: 167 Silent_Buffer(); 168 blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ); 169 void clock_rate( long ) { } 170 void bass_freq( int ) { } 171 void clear() { } 172 channel_t channel( int ) { return chan; } 173 void end_frame( blip_time_t ) { } 174 long samples_avail() const { return 0; } 175 long read_samples( blip_sample_t*, long ) { return 0; } 176}; 177 178 179inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec ) 180{ 181 sample_rate_ = rate; 182 length_ = msec; 183 return 0; 184} 185 186inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec ) 187{ 188 return Multi_Buffer::set_sample_rate( rate, msec ); 189} 190 191inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; } 192 193inline long Multi_Buffer::sample_rate() const { return sample_rate_; } 194 195inline int Multi_Buffer::length() const { return length_; } 196 197inline blargg_err_t Multi_Buffer::set_channel_count( int n, int const* types ) 198{ 199 channel_count_ = n; 200 channel_types_ = types; 201 return 0; 202} 203 204#endif