"Fossies" - the Fresh Open Source Software Archive

Member "audacious-plugins-3.10.1/src/console/Blip_Buffer.h" (26 Dec 2018, 15777 Bytes) of package /linux/misc/audacious-plugins-3.10.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Blip_Buffer.h" see the Fossies "Dox" file reference documentation.

    1 // Band-limited sound synthesis buffer
    2 
    3 // Blip_Buffer 0.4.1
    4 #ifndef BLIP_BUFFER_H
    5 #define BLIP_BUFFER_H
    6 
    7     // internal
    8     #include <limits.h>
    9     #if INT_MAX < 0x7FFFFFFF
   10         #error "int must be at least 32 bits"
   11     #endif
   12 
   13     typedef int blip_long;
   14     typedef unsigned blip_ulong;
   15 
   16 // Time unit at source clock rate
   17 typedef blip_long blip_time_t;
   18 
   19 // Output samples are 16-bit signed, with a range of -32768 to 32767
   20 typedef short blip_sample_t;
   21 enum { blip_sample_max = 32767 };
   22 
   23 class Blip_Buffer {
   24 public:
   25     typedef const char* blargg_err_t;
   26 
   27     // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
   28     // to 1/4 second), then clear buffer. Returns nullptr on success, otherwise if there
   29     // isn't enough memory, returns error without affecting current buffer setup.
   30     blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
   31 
   32     // Set number of source time units per second
   33     void clock_rate( long );
   34 
   35     // End current time frame of specified duration and make its samples available
   36     // (along with any still-unread samples) for reading with read_samples(). Begins
   37     // a new time frame at the end of the current frame.
   38     void end_frame( blip_time_t time );
   39 
   40     // Read at most 'max_samples' out of buffer into 'dest', removing them from from
   41     // the buffer. Returns number of samples actually read and removed. If stereo is
   42     // true, increments 'dest' one extra time after writing each sample, to allow
   43     // easy interleving of two channels into a stereo output buffer.
   44     long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
   45 
   46 // Additional optional features
   47 
   48     // Current output sample rate
   49     long sample_rate() const;
   50 
   51     // Length of buffer, in milliseconds
   52     int length() const;
   53 
   54     // Number of source time units per second
   55     long clock_rate() const;
   56 
   57     // Set frequency high-pass filter frequency, where higher values reduce bass more
   58     void bass_freq( int frequency );
   59 
   60     // Number of samples delay from synthesis to samples read out
   61     int output_latency() const;
   62 
   63     // Remove all available samples and clear buffer to silence. If 'entire_buffer' is
   64     // false, just clears out any samples waiting rather than the entire buffer.
   65     void clear( int entire_buffer = 1 );
   66 
   67     // Number of samples available for reading with read_samples()
   68     long samples_avail() const;
   69 
   70     // Remove 'count' samples from those waiting to be read
   71     void remove_samples( long count );
   72 
   73 // Experimental features
   74 
   75     // Count number of clocks needed until 'count' samples will be available.
   76     // If buffer can't even hold 'count' samples, returns number of clocks until
   77     // buffer becomes full.
   78     blip_time_t count_clocks( long count ) const;
   79 
   80     // Number of raw samples that can be mixed within frame of specified duration.
   81     long count_samples( blip_time_t duration ) const;
   82 
   83     // Mix 'count' samples from 'buf' into buffer.
   84     void mix_samples( blip_sample_t const* buf, long count );
   85 
   86     // not documented yet
   87     void set_modified() { modified_ = 1; }
   88     int clear_modified() { int b = modified_; modified_ = 0; return b; }
   89     typedef blip_ulong blip_resampled_time_t;
   90     void remove_silence( long count );
   91     blip_resampled_time_t resampled_duration( int t ) const     { return t * factor_; }
   92     blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
   93     blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
   94 public:
   95     Blip_Buffer();
   96     ~Blip_Buffer();
   97 
   98     // Deprecated
   99     typedef blip_resampled_time_t resampled_time_t;
  100     blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
  101     blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
  102 private:
  103     // noncopyable
  104     Blip_Buffer( const Blip_Buffer& );
  105     Blip_Buffer& operator = ( const Blip_Buffer& );
  106 public:
  107     typedef blip_time_t buf_t_;
  108     blip_ulong factor_;
  109     blip_resampled_time_t offset_;
  110     buf_t_* buffer_;
  111     blip_long buffer_size_;
  112     blip_long reader_accum_;
  113     int bass_shift_;
  114 private:
  115     long sample_rate_;
  116     long clock_rate_;
  117     int bass_freq_;
  118     int length_;
  119     int modified_;
  120     friend class Blip_Reader;
  121 };
  122 
  123 // Number of bits in resample ratio fraction. Higher values give a more accurate ratio
  124 // but reduce maximum buffer size.
  125 #ifndef BLIP_BUFFER_ACCURACY
  126     #define BLIP_BUFFER_ACCURACY 16
  127 #endif
  128 
  129 // Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
  130 // noticeable broadband noise when synthesizing high frequency square waves.
  131 // Affects size of Blip_Synth objects since they store the waveform directly.
  132 #ifndef BLIP_PHASE_BITS
  133     #if BLIP_BUFFER_FAST
  134         #define BLIP_PHASE_BITS 8
  135     #else
  136         #define BLIP_PHASE_BITS 6
  137     #endif
  138 #endif
  139 
  140     // Internal
  141     typedef blip_ulong blip_resampled_time_t;
  142     int const blip_widest_impulse_ = 16;
  143     int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
  144     int const blip_res = 1 << BLIP_PHASE_BITS;
  145     class blip_eq_t;
  146 
  147     class Blip_Synth_Fast_ {
  148     public:
  149         Blip_Buffer* buf;
  150         int last_amp;
  151         int delta_factor;
  152 
  153         void volume_unit( double );
  154         Blip_Synth_Fast_();
  155         void treble_eq( blip_eq_t const& ) { }
  156     };
  157 
  158     class Blip_Synth_ {
  159     public:
  160         Blip_Buffer* buf;
  161         int last_amp;
  162         int delta_factor;
  163 
  164         void volume_unit( double );
  165         Blip_Synth_( short* impulses, int width );
  166         void treble_eq( blip_eq_t const& );
  167     private:
  168         double volume_unit_;
  169         short* const impulses;
  170         int const width;
  171         blip_long kernel_unit;
  172         int impulses_size() const { return blip_res / 2 * width + 1; }
  173         void adjust_impulse();
  174     };
  175 
  176 // Quality level. Start with blip_good_quality.
  177 const int blip_med_quality  = 8;
  178 const int blip_good_quality = 12;
  179 const int blip_high_quality = 16;
  180 
  181 // Range specifies the greatest expected change in amplitude. Calculate it
  182 // by finding the difference between the maximum and minimum expected
  183 // amplitudes (max - min).
  184 template<int quality,int range>
  185 class Blip_Synth {
  186 public:
  187     // Set overall volume of waveform
  188     void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
  189 
  190     // Configure low-pass filter (see blip_buffer.txt)
  191     void treble_eq( blip_eq_t const& eq )       { impl.treble_eq( eq ); }
  192 
  193     // Get/set Blip_Buffer used for output
  194     Blip_Buffer* output() const                 { return impl.buf; }
  195     void output( Blip_Buffer* b )               { impl.buf = b; impl.last_amp = 0; }
  196 
  197     // Update amplitude of waveform at given time. Using this requires a separate
  198     // Blip_Synth for each waveform.
  199     void update( blip_time_t time, int amplitude );
  200 
  201 // Low-level interface
  202 
  203     // Add an amplitude transition of specified delta, optionally into specified buffer
  204     // rather than the one set with output(). Delta can be positive or negative.
  205     // The actual change in amplitude is delta * (volume / range)
  206     void offset( blip_time_t, int delta, Blip_Buffer* ) const;
  207     void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
  208 
  209     // Works directly in terms of fractional output samples. Contact author for more info.
  210     void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
  211 
  212     // Same as offset(), except code is inlined for higher performance
  213     void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
  214         offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
  215     }
  216     void offset_inline( blip_time_t t, int delta ) const {
  217         offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
  218     }
  219 
  220 private:
  221 #if BLIP_BUFFER_FAST
  222     Blip_Synth_Fast_ impl;
  223 #else
  224     Blip_Synth_ impl;
  225     typedef short imp_t;
  226     imp_t impulses [blip_res * (quality / 2) + 1];
  227 public:
  228     Blip_Synth() : impl( impulses, quality ) { }
  229 #endif
  230 };
  231 
  232 // Low-pass equalization parameters
  233 class blip_eq_t {
  234 public:
  235     // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
  236     // treble, small positive values (0 to 5.0) increase treble.
  237     blip_eq_t( double treble_db = 0 );
  238 
  239     // See blip_buffer.txt
  240     blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
  241 
  242 private:
  243     double treble;
  244     long rolloff_freq;
  245     long sample_rate;
  246     long cutoff_freq;
  247     void generate( float* out, int count ) const;
  248     friend class Blip_Synth_;
  249 };
  250 
  251 int const blip_sample_bits = 30;
  252 
  253 // Dummy Blip_Buffer to direct sound output to, for easy muting without
  254 // having to stop sound code.
  255 class Silent_Blip_Buffer : public Blip_Buffer {
  256     buf_t_ buf [blip_buffer_extra_ + 1];
  257 public:
  258     // The following cannot be used (an assertion will fail if attempted):
  259     blargg_err_t set_sample_rate( long samples_per_sec, int msec_length );
  260     blip_time_t count_clocks( long count ) const;
  261     void mix_samples( blip_sample_t const* buf, long count );
  262 
  263     Silent_Blip_Buffer();
  264 };
  265 
  266     #if defined (__GNUC__) || _MSC_VER >= 1100
  267         #define BLIP_RESTRICT __restrict
  268     #else
  269         #define BLIP_RESTRICT
  270     #endif
  271 
  272 // Optimized reading from Blip_Buffer, for use in custom sample output
  273 
  274 // Begin reading from buffer. Name should be unique to the current block.
  275 #define BLIP_READER_BEGIN( name, blip_buffer ) \
  276     const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
  277     blip_long name##_reader_accum = (blip_buffer).reader_accum_
  278 
  279 // Get value to pass to BLIP_READER_NEXT()
  280 #define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
  281 
  282 // Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
  283 // code at the cost of having no bass control
  284 int const blip_reader_default_bass = 9;
  285 
  286 // Current sample
  287 #define BLIP_READER_READ( name )        (name##_reader_accum >> (blip_sample_bits - 16))
  288 
  289 // Current raw sample in full internal resolution
  290 #define BLIP_READER_READ_RAW( name )    (name##_reader_accum)
  291 
  292 // Advance to next sample
  293 #define BLIP_READER_NEXT( name, bass ) \
  294     (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
  295 
  296 // End reading samples from buffer. The number of samples read must now be removed
  297 // using Blip_Buffer::remove_samples().
  298 #define BLIP_READER_END( name, blip_buffer ) \
  299     (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
  300 
  301 
  302 // Compatibility with older version
  303 const long blip_unscaled = 65535;
  304 const int blip_low_quality  = blip_med_quality;
  305 const int blip_best_quality = blip_high_quality;
  306 
  307 // Deprecated; use BLIP_READER macros as follows:
  308 // Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
  309 // int bass = r.begin( buf )      -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
  310 // r.read()                       -> BLIP_READER_READ( r )
  311 // r.read_raw()                   -> BLIP_READER_READ_RAW( r )
  312 // r.next( bass )                 -> BLIP_READER_NEXT( r, bass )
  313 // r.next()                       -> BLIP_READER_NEXT( r, blip_reader_default_bass )
  314 // r.end( buf )                   -> BLIP_READER_END( r, buf )
  315 class Blip_Reader {
  316 public:
  317     int begin( Blip_Buffer& );
  318     blip_long read() const          { return accum >> (blip_sample_bits - 16); }
  319     blip_long read_raw() const      { return accum; }
  320     void next( int bass_shift = 9 )         { accum += *buf++ - (accum >> bass_shift); }
  321     void end( Blip_Buffer& b )              { b.reader_accum_ = accum; }
  322 
  323 private:
  324     const Blip_Buffer::buf_t_* buf;
  325     blip_long accum;
  326 };
  327 
  328 // End of public interface
  329 
  330 #include <assert.h>
  331 
  332 template<int quality,int range>
  333 inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
  334         int delta, Blip_Buffer* blip_buf ) const
  335 {
  336     // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
  337     // need for a longer buffer as set by set_sample_rate().
  338     assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
  339     delta *= impl.delta_factor;
  340     blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
  341     int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
  342 
  343 #if BLIP_BUFFER_FAST
  344     blip_long left = buf [0] + delta;
  345 
  346     // Kind of crappy, but doing shift after multiply results in overflow.
  347     // Alternate way of delaying multiply by delta_factor results in worse
  348     // sub-sample resolution.
  349     blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
  350     left  -= right;
  351     right += buf [1];
  352 
  353     buf [0] = left;
  354     buf [1] = right;
  355 #else
  356 
  357     int const fwd = (blip_widest_impulse_ - quality) / 2;
  358     int const rev = fwd + quality - 2;
  359     int const mid = quality / 2 - 1;
  360 
  361     imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase;
  362 
  363     #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
  364             defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
  365 
  366     // straight forward implementation resulted in better code on GCC for x86
  367 
  368     #define ADD_IMP( out, in ) \
  369         buf [out] += (blip_long) imp [blip_res * (in)] * delta
  370 
  371     #define BLIP_FWD( i ) {\
  372         ADD_IMP( fwd     + i, i     );\
  373         ADD_IMP( fwd + 1 + i, i + 1 );\
  374     }
  375     #define BLIP_REV( r ) {\
  376         ADD_IMP( rev     - r, r + 1 );\
  377         ADD_IMP( rev + 1 - r, r     );\
  378     }
  379 
  380         BLIP_FWD( 0 )
  381         if ( quality > 8  ) BLIP_FWD( 2 )
  382         if ( quality > 12 ) BLIP_FWD( 4 )
  383         {
  384             ADD_IMP( fwd + mid - 1, mid - 1 );
  385             ADD_IMP( fwd + mid    , mid     );
  386             imp = impulses + phase;
  387         }
  388         if ( quality > 12 ) BLIP_REV( 6 )
  389         if ( quality > 8  ) BLIP_REV( 4 )
  390         BLIP_REV( 2 )
  391 
  392         ADD_IMP( rev    , 1 );
  393         ADD_IMP( rev + 1, 0 );
  394 
  395     #else
  396 
  397     // for RISC processors, help compiler by reading ahead of writes
  398 
  399     #define BLIP_FWD( i ) {\
  400         blip_long t0 =                       i0 * delta + buf [fwd     + i];\
  401         blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\
  402         i0 =           imp [blip_res * (i + 2)];\
  403         buf [fwd     + i] = t0;\
  404         buf [fwd + 1 + i] = t1;\
  405     }
  406     #define BLIP_REV( r ) {\
  407         blip_long t0 =                 i0 * delta + buf [rev     - r];\
  408         blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\
  409         i0 =           imp [blip_res * (r - 1)];\
  410         buf [rev     - r] = t0;\
  411         buf [rev + 1 - r] = t1;\
  412     }
  413 
  414         blip_long i0 = *imp;
  415         BLIP_FWD( 0 )
  416         if ( quality > 8  ) BLIP_FWD( 2 )
  417         if ( quality > 12 ) BLIP_FWD( 4 )
  418         {
  419             blip_long t0 =                   i0 * delta + buf [fwd + mid - 1];
  420             blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid    ];
  421             imp = impulses + phase;
  422             i0 = imp [blip_res * mid];
  423             buf [fwd + mid - 1] = t0;
  424             buf [fwd + mid    ] = t1;
  425         }
  426         if ( quality > 12 ) BLIP_REV( 6 )
  427         if ( quality > 8  ) BLIP_REV( 4 )
  428         BLIP_REV( 2 )
  429 
  430         blip_long t0 =   i0 * delta + buf [rev    ];
  431         blip_long t1 = *imp * delta + buf [rev + 1];
  432         buf [rev    ] = t0;
  433         buf [rev + 1] = t1;
  434     #endif
  435 
  436 #endif
  437 }
  438 
  439 #undef BLIP_FWD
  440 #undef BLIP_REV
  441 
  442 template<int quality,int range>
  443 #if BLIP_BUFFER_FAST
  444     inline
  445 #endif
  446 void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
  447 {
  448     offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
  449 }
  450 
  451 template<int quality,int range>
  452 #if BLIP_BUFFER_FAST
  453     inline
  454 #endif
  455 void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
  456 {
  457     int delta = amp - impl.last_amp;
  458     impl.last_amp = amp;
  459     offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
  460 }
  461 
  462 inline blip_eq_t::blip_eq_t( double t ) :
  463         treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
  464 inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
  465         treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
  466 
  467 inline int  Blip_Buffer::length() const         { return length_; }
  468 inline long Blip_Buffer::samples_avail() const  { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
  469 inline long Blip_Buffer::sample_rate() const    { return sample_rate_; }
  470 inline int  Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
  471 inline long Blip_Buffer::clock_rate() const     { return clock_rate_; }
  472 inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
  473 
  474 inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
  475 {
  476     buf = blip_buf.buffer_;
  477     accum = blip_buf.reader_accum_;
  478     return blip_buf.bass_shift_;
  479 }
  480 
  481 int const blip_max_length = 0;
  482 int const blip_default_length = 250;
  483 
  484 #endif