Mercurial > audlegacy
view Plugins/Input/console/Blip_Buffer.h @ 137:b8d4c1faa6d7 trunk
[svn] Import WMA decoder into SVN.
author | nenolod |
---|---|
date | Thu, 10 Nov 2005 14:56:35 -0800 |
parents | 252843aac42f |
children | 7c5e886205ef |
line wrap: on
line source
// Buffer of sound samples into which band-limited waveforms can be synthesized // using Blip_Wave or Blip_Synth. // Blip_Buffer 0.3.3. Copyright (C) 2003-2005 Shay Green. GNU LGPL license. #ifndef BLIP_BUFFER_H #define BLIP_BUFFER_H #include "blargg_common.h" class Blip_Reader; // Source time unit. typedef long blip_time_t; // Type of sample produced. Signed 16-bit format. typedef BOOST::int16_t blip_sample_t; // Make buffer as large as possible (currently about 65000 samples) const int blip_default_length = 0; class Blip_Buffer { public: // Construct an empty buffer. Blip_Buffer(); ~Blip_Buffer(); // Set output sample rate and buffer length in milliseconds (1/1000 sec), // then clear buffer. If length is not specified, make as large as possible. // If there is insufficient memory for the buffer, sets the buffer length // to 0 and returns error string (or propagates exception if compiler supports it). blargg_err_t sample_rate( long samples_per_sec, int msec_length = blip_default_length ); // Length of buffer, in milliseconds int length() const; // Current output sample rate long sample_rate() const; // Number of source time units per second void clock_rate( long ); long clock_rate() const; // Set frequency at which high-pass filter attenuation passes -3dB void bass_freq( int frequency ); // Remove all available samples and clear buffer to silence. If 'entire_buffer' is // false, just clear out any samples waiting rather than the entire buffer. void clear( bool entire_buffer = true ); // End current time frame of specified duration and make its samples available // (along with any still-unread samples) for reading with read_samples(). Begin // a new time frame at the end of the current frame. All transitions must have // been added before 'time'. void end_frame( blip_time_t time ); // Number of samples available for reading with read_samples() long samples_avail() const; // Read at most 'max_samples' out of buffer into 'dest', removing them from from // the buffer. Return number of samples actually read and removed. If stereo is // true, increment 'dest' one extra time after writing each sample, to allow // easy interleving of two channels into a stereo output buffer. long read_samples( blip_sample_t* dest, long max_samples, bool stereo = false ); // Remove 'count' samples from those waiting to be read void remove_samples( long count ); // Number of samples delay from synthesis to samples read out int output_latency() const; // Experimental external buffer mixing support // Number of raw samples that can be mixed within frame of specified duration long count_samples( blip_time_t duration ) const; // Mix 'count' samples from 'buf' into buffer. void mix_samples( const blip_sample_t* buf, long count ); // not documented yet void remove_silence( long count ); typedef unsigned long resampled_time_t; resampled_time_t resampled_time( blip_time_t t ) const { return t * resampled_time_t (factor_) + offset_; } resampled_time_t resampled_duration( int t ) const { return t * resampled_time_t (factor_); } private: // noncopyable Blip_Buffer( const Blip_Buffer& ); Blip_Buffer& operator = ( const Blip_Buffer& ); // Don't use the following members. They are public only for technical reasons. public: enum { widest_impulse_ = 24 }; typedef BOOST::uint16_t buf_t_; unsigned long factor_; resampled_time_t offset_; buf_t_* buffer_; unsigned buffer_size_; private: long reader_accum; int bass_shift; long samples_per_sec; long clocks_per_sec; int bass_freq_; int length_; enum { accum_fract = 15 }; // less than 16 to give extra sample range enum { sample_offset = 0x7F7F }; // repeated byte allows memset to clear buffer friend class Blip_Reader; }; // Low-pass equalization parameters (see notes.txt) class blip_eq_t { public: blip_eq_t( double treble = 0 ); blip_eq_t( double treble, long cutoff, long sample_rate ); private: double treble; long cutoff; long sample_rate; friend class Blip_Impulse_; }; // not documented yet (see Multi_Buffer.cpp for an example of use) class Blip_Reader { const Blip_Buffer::buf_t_* buf; long accum; #ifdef __MWERKS__ void operator = ( struct foobar ); // helps optimizer #endif public: // avoid anything which might cause optimizer to put object in memory int begin( Blip_Buffer& blip_buf ) { buf = blip_buf.buffer_; accum = blip_buf.reader_accum; return blip_buf.bass_shift; } int read() const { return accum >> Blip_Buffer::accum_fract; } void next( int bass_shift = 9 ) { accum -= accum >> bass_shift; accum += ((long) *buf++ - Blip_Buffer::sample_offset) << Blip_Buffer::accum_fract; } void end( Blip_Buffer& blip_buf ) { blip_buf.reader_accum = accum; } }; // End of public interface #ifndef BLIP_BUFFER_ACCURACY #define BLIP_BUFFER_ACCURACY 16 #endif const int blip_res_bits_ = 5; typedef BOOST::uint32_t blip_pair_t_; class Blip_Impulse_ { typedef BOOST::uint16_t imp_t; blip_eq_t eq; double volume_unit_; imp_t* impulses; imp_t* impulse; int width; int fine_bits; int res; bool generate; void fine_volume_unit(); void scale_impulse( int unit, imp_t* ) const; public: Blip_Buffer* buf; BOOST::uint32_t offset; void init( blip_pair_t_* impulses, int width, int res, int fine_bits = 0 ); void volume_unit( double ); void treble_eq( const blip_eq_t& ); }; inline blip_eq_t::blip_eq_t( double t ) : treble( t ), cutoff( 0 ), sample_rate( 44100 ) { } inline blip_eq_t::blip_eq_t( double t, long c, long sr ) : treble( t ), cutoff( c ), sample_rate( sr ) { } inline int Blip_Buffer::length() const { return length_; } inline long Blip_Buffer::samples_avail() const { return long (offset_ >> BLIP_BUFFER_ACCURACY); } inline long Blip_Buffer::sample_rate() const { return samples_per_sec; } inline void Blip_Buffer::end_frame( blip_time_t t ) { offset_ += t * factor_; assert(( "Blip_Buffer::end_frame(): Frame went past end of buffer", samples_avail() <= buffer_size_ )); } inline void Blip_Buffer::remove_silence( long count ) { assert(( "Blip_Buffer::remove_silence(): Tried to remove more samples than available", count <= samples_avail() )); offset_ -= resampled_time_t (count) << BLIP_BUFFER_ACCURACY; } inline int Blip_Buffer::output_latency() const { return widest_impulse_ / 2; } inline long Blip_Buffer::clock_rate() const { return clocks_per_sec; } // MSVC6 fix typedef Blip_Buffer::resampled_time_t blip_resampled_time_t; #include "Blip_Synth.h" #endif