Simplify Blip_Buffer.cpp and Stereo_Buffer.cpp

This commit is contained in:
libretroadmin 2022-06-19 02:45:25 +02:00
parent 7b5e21a7d9
commit 778be26770
8 changed files with 67 additions and 290 deletions

View File

@ -66,11 +66,8 @@ BACKSLASH := \$(BACKSLASH)
filter_out1 = $(filter-out $(firstword $1),$1)
filter_out2 = $(call filter_out1,$(call filter_out1,$1))
NEED_BPP = 16
NEED_BLIP = 1
NEED_STEREO_SOUND = 1
prefix := /usr
libdir := $(prefix)/lib

View File

@ -71,10 +71,6 @@ ifeq ($(NO_COMPUTED_GOTO), 1)
FLAGS += -DNO_COMPUTED_GOTO
endif
ifeq ($(NEED_STEREO_SOUND), 1)
FLAGS += -DWANT_STEREO_SOUND
endif
ifeq ($(FRONTEND_SUPPORTS_RGB565), 1)
FLAGS += -DFRONTEND_SUPPORTS_RGB565
endif

View File

@ -6,7 +6,6 @@ DEBUG := 0
FRONTEND_SUPPORTS_RGB565 := 1
NEED_BPP := 16
NEED_BLIP := 1
NEED_STEREO_SOUND := 1
IS_X86 := 0
LOAD_FROM_MEMORY := 1
FLAGS :=

View File

@ -15,26 +15,16 @@
#define BLIP_BUFFER_H
// Internal
typedef int32_t blip_long;
typedef uint32_t blip_ulong;
typedef int64_t blip_s64;
typedef uint64_t blip_u64;
// Time unit at source clock rate
typedef blip_long blip_time_t;
// Output samples are 16-bit signed, with a range of -32768 to 32767
typedef short blip_sample_t;
enum { blip_sample_max = 32767 };
#define BLIP_SAMPLE_MAX 32767
class Blip_Buffer {
public:
typedef const char* blargg_err_t;
// Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
// to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
// isn't enough memory, returns error without affecting current buffer setup.
blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
// to 1/4 second), then clear buffer. Returns 0 on success, otherwise if there
// isn't enough memory, returns -1.
int set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
// Set number of source time units per second
void clock_rate( long );
@ -42,13 +32,13 @@ public:
// End current time frame of specified duration and make its samples available
// (along with any still-unread samples) for reading with read_samples(). Begins
// a new time frame at the end of the current frame.
void end_frame( blip_time_t time );
void end_frame( int32_t time );
// Read at most 'max_samples' out of buffer into 'dest', removing them from from
// the buffer. Returns number of samples actually read and removed. If stereo is
// true, increments '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, int stereo = 0 );
long read_samples( int16_t* dest, long max_samples);
// Additional optional features
@ -64,9 +54,6 @@ public:
// Set frequency high-pass filter frequency, where higher values reduce bass more
void bass_freq( int frequency );
// Number of samples delay from synthesis to samples read out
int output_latency() const;
// Remove all available samples and clear buffer to silence. If 'entire_buffer' is
// false, just clears out any samples waiting rather than the entire buffer.
void clear( int entire_buffer = 1 );
@ -79,51 +66,28 @@ public:
// Experimental features
// Count number of clocks needed until 'count' samples will be available.
// If buffer can't even hold 'count' samples, returns number of clocks until
// buffer becomes full.
blip_time_t count_clocks( long count ) const;
// 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( blip_sample_t const* buf, long count );
// not documented yet
void set_modified() { modified_ = 1; }
int clear_modified() { int b = modified_; modified_ = 0; return b; }
typedef blip_u64 blip_resampled_time_t;
void remove_silence( long count );
blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
uint64_t clock_rate_factor( long clock_rate ) const;
public:
Blip_Buffer();
~Blip_Buffer();
// Deprecated
typedef blip_resampled_time_t resampled_time_t;
blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
private:
// noncopyable
Blip_Buffer( const Blip_Buffer& );
Blip_Buffer& operator = ( const Blip_Buffer& );
public:
typedef blip_time_t buf_t_;
blip_u64 factor_;
blip_resampled_time_t offset_;
buf_t_* buffer_;
blip_long buffer_size_;
blip_long reader_accum_;
uint64_t factor_;
uint64_t offset_;
int32_t *buffer_;
int32_t buffer_size_;
int32_t reader_accum_;
int bass_shift_;
private:
long sample_rate_;
long clock_rate_;
int bass_freq_;
int length_;
int modified_;
friend class Blip_Reader;
};
@ -134,25 +98,7 @@ private:
#define BLIP_BUFFER_ACCURACY 32
#define BLIP_PHASE_BITS 8
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
// but reduce maximum buffer size.
//#ifndef BLIP_BUFFER_ACCURACY
// #define BLIP_BUFFER_ACCURACY 16
//#endif
// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
// noticeable broadband noise when synthesizing high frequency square waves.
// Affects size of Blip_Synth objects since they store the waveform directly.
//#ifndef BLIP_PHASE_BITS
// #if BLIP_BUFFER_FAST
// #define BLIP_PHASE_BITS 8
// #else
// #define BLIP_PHASE_BITS 6
// #endif
//#endif
// Internal
typedef blip_u64 blip_resampled_time_t;
int const blip_widest_impulse_ = 16;
int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
int const blip_res = 1 << BLIP_PHASE_BITS;
@ -182,9 +128,7 @@ private:
double volume_unit_;
short* const impulses;
int const width;
blip_long kernel_unit;
int impulses_size() const { return blip_res / 2 * width + 1; }
void adjust_impulse();
int32_t kernel_unit;
};
// Quality level. Start with blip_good_quality.
@ -210,24 +154,24 @@ public:
// Update amplitude of waveform at given time. Using this requires a separate
// Blip_Synth for each waveform.
void update( blip_time_t time, int amplitude );
void update( int32_t time, int amplitude );
// Low-level interface
// Add an amplitude transition of specified delta, optionally into specified buffer
// rather than the one set with output(). Delta can be positive or negative.
// The actual change in amplitude is delta * (volume / range)
void offset( blip_time_t, int delta, Blip_Buffer* ) const;
void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
void offset( int32_t, int delta, Blip_Buffer* ) const;
void offset( int32_t t, int delta ) const { offset( t, delta, impl.buf ); }
// Works directly in terms of fractional output samples. Contact author for more info.
void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
void offset_resampled( uint64_t, int delta, Blip_Buffer* ) const;
// Same as offset(), except code is inlined for higher performance
void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
void offset_inline( int32_t t, int delta, Blip_Buffer* buf ) const {
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
}
void offset_inline( blip_time_t t, int delta ) const {
void offset_inline( int32_t t, int delta ) const {
offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
}
@ -254,7 +198,7 @@ private:
friend class Blip_Synth_;
};
int const blip_sample_bits = 30;
#define BLIP_SAMPLE_BITS 30
#define BLIP_RESTRICT
@ -262,8 +206,8 @@ int const blip_sample_bits = 30;
// Begin reading from buffer. Name should be unique to the current block.
#define BLIP_READER_BEGIN( name, blip_buffer ) \
const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
blip_long name##_reader_accum = (blip_buffer).reader_accum_
const int32_t * BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
int32_t name##_reader_accum = (blip_buffer).reader_accum_
// Get value to pass to BLIP_READER_NEXT()
#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
@ -273,7 +217,7 @@ int const blip_sample_bits = 30;
int const blip_reader_default_bass = 9;
// Current sample
#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
#define BLIP_READER_READ( name ) (name##_reader_accum >> (BLIP_SAMPLE_BITS - 16))
// Current raw sample in full internal resolution
#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
@ -287,49 +231,41 @@ int const blip_reader_default_bass = 9;
#define BLIP_READER_END( name, blip_buffer ) \
(void) ((blip_buffer).reader_accum_ = name##_reader_accum)
// Compatibility with older version
const long blip_unscaled = 65535;
const int blip_low_quality = blip_med_quality;
const int blip_best_quality = blip_high_quality;
// Deprecated; use BLIP_READER macros as follows:
// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf );
// r.read() -> BLIP_READER_READ( r )
// r.read_raw() -> BLIP_READER_READ_RAW( r )
// r.next( bass ) -> BLIP_READER_NEXT( r, bass )
// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass )
// r.end( buf ) -> BLIP_READER_END( r, buf )
class Blip_Reader {
public:
int begin( Blip_Buffer& );
blip_long read() const { return accum >> (blip_sample_bits - 16); }
blip_long read_raw() const { return accum; }
int32_t read() const { return accum >> (BLIP_SAMPLE_BITS - 16); }
void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
private:
const Blip_Buffer::buf_t_* buf;
blip_long accum;
const int32_t *buf;
int32_t accum;
};
// End of public interface
template<int quality,int range>
blip_inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
blip_inline void Blip_Synth<quality,range>::offset_resampled( uint64_t time,
int delta, Blip_Buffer* blip_buf ) const
{
delta *= impl.delta_factor;
blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
int32_t *BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
blip_long left = buf [0] + delta;
int32_t left = buf [0] + delta;
// Kind of crappy, but doing shift after multiply results in overflow.
// Alternate way of delaying multiply by delta_factor results in worse
// sub-sample resolution.
blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
int32_t right = (delta >> BLIP_PHASE_BITS) * phase;
left -= right;
right += buf [1];
@ -341,13 +277,13 @@ blip_inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_tim
#undef BLIP_REV
template<int quality,int range>
blip_inline void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
blip_inline void Blip_Synth<quality,range>::offset( int32_t t, int delta, Blip_Buffer* buf ) const
{
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
}
template<int quality,int range>
blip_inline void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
blip_inline void Blip_Synth<quality,range>::update( int32_t t, int amp )
{
int delta = amp - impl.last_amp;
impl.last_amp = amp;
@ -362,7 +298,6 @@ blip_inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
blip_inline int Blip_Buffer::length() const { return length_; }
blip_inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
blip_inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
blip_inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
blip_inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
blip_inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }

View File

@ -28,12 +28,12 @@ public:
// Same as in Blip_Buffer. For more efficient operation, pass false
// for was_stereo if the left and right buffers had nothing added
// to them for this frame.
void end_frame( blip_time_t, bool was_stereo = true );
void end_frame( int32_t);
// Output is stereo with channels interleved, left before right. Counts
// are in samples, *not* pairs.
long samples_avail() const;
long read_samples( blip_sample_t*, long );
long read_samples( int16_t*, long );
private:
// noncopyable
@ -45,10 +45,7 @@ private:
bool stereo_added;
bool was_stereo;
void mix_stereo( blip_sample_t*, long );
void mix_mono( blip_sample_t*, long );
void mix_stereo( float*, long );
void mix_mono( float*, long );
void mix_stereo( int16_t*, long );
};
inline Blip_Buffer* Stereo_Buffer::left() {

View File

@ -27,28 +27,18 @@ extern "C" void MDFNNGPCSOUND_SetEnable(bool set)
apu.reset();
}
static void Write_SoundChipLeftInternal(uint8_t data)
extern "C" void Write_SoundChipLeft(uint8_t data)
{
if(schipenable)
apu.write_data_left(ngpc_soundTS >> 1, data);
}
static void Write_SoundChipRightInternal(uint8_t data)
extern "C" void Write_SoundChipRight(uint8_t data)
{
if(schipenable)
apu.write_data_right(ngpc_soundTS >> 1, data);
}
extern "C" void Write_SoundChipLeft(uint8_t data)
{
Write_SoundChipLeftInternal(data);
}
extern "C" void Write_SoundChipRight(uint8_t data)
{
Write_SoundChipRightInternal(data);
}
extern "C" void dac_write_left(uint8_t data)
{
CurrentDACLeft = data;
@ -72,7 +62,6 @@ extern "C" int32_t MDFNNGPCSOUND_Flush(int16_t *SoundBuf, const int32_t MaxSound
int32_t FrameCount = 0;
apu.end_frame(ngpc_soundTS >> 1);
buf.end_frame(ngpc_soundTS >> 1);
if(SoundBuf)
@ -83,19 +72,14 @@ extern "C" int32_t MDFNNGPCSOUND_Flush(int16_t *SoundBuf, const int32_t MaxSound
return(FrameCount);
}
static void RedoVolume(void)
{
apu.output(buf.center(), buf.left(), buf.right());
apu.volume(0.30);
synth.volume(0.40);
}
extern "C" void MDFNNGPCSOUND_Init(void)
{
MDFNNGPC_SetSoundRate(0);
buf.clock_rate((long)(3072000));
RedoVolume();
apu.output(buf.center(), buf.left(), buf.right());
apu.volume(0.30);
synth.volume(0.40);
buf.bass_freq(20);
}

View File

@ -20,7 +20,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
Blip_Buffer::Blip_Buffer()
{
factor_ = (blip_u64)ULLONG_MAX;
factor_ = (uint64_t)ULLONG_MAX;
offset_ = 0;
buffer_ = 0;
buffer_size_ = 0;
@ -42,18 +42,17 @@ void Blip_Buffer::clear( int entire_buffer )
{
offset_ = 0;
reader_accum_ = 0;
modified_ = 0;
if ( buffer_ )
{
long count = (entire_buffer ? buffer_size_ : samples_avail());
memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (buf_t_) );
memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof (int32_t) );
}
}
Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
int Blip_Buffer::set_sample_rate( long new_rate, int msec )
{
// start with maximum length that resampled time can represent
blip_s64 new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
int64_t new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
// simple safety check, since code elsewhere may not be safe for sizes approaching (2 ^ 31).
if(new_size > ((1LL << 30) - 1))
@ -61,7 +60,7 @@ Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec
if ( msec != blip_max_length )
{
blip_s64 s = ((blip_s64)new_rate * (msec + 1) + 999) / 1000;
int64_t s = ((int64_t)new_rate * (msec + 1) + 999) / 1000;
if ( s < new_size )
new_size = s;
}
@ -70,9 +69,9 @@ Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec
{
void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * sizeof *buffer_ );
if ( !p )
return "Out of memory";
return -1;
buffer_ = (buf_t_*) p;
buffer_ = (int32_t*) p;
}
buffer_size_ = new_size;
@ -89,11 +88,11 @@ Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec
return 0; // success
}
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
uint64_t Blip_Buffer::clock_rate_factor( long rate ) const
{
double ratio = (double) sample_rate_ / rate;
blip_s64 factor = (blip_s64) floor( ratio * (1LL << BLIP_BUFFER_ACCURACY) + 0.5 );
return (blip_resampled_time_t) factor;
double ratio = (double) sample_rate_ / rate;
int64_t factor = (int64_t) floor( ratio * (1LL << BLIP_BUFFER_ACCURACY) + 0.5 );
return (uint64_t) factor;
}
void Blip_Buffer::bass_freq( int freq )
@ -109,32 +108,14 @@ void Blip_Buffer::bass_freq( int freq )
bass_shift_ = shift;
}
void Blip_Buffer::end_frame( blip_time_t t )
void Blip_Buffer::end_frame( int32_t t )
{
offset_ += t * factor_;
}
void Blip_Buffer::remove_silence( long count )
{
offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
}
long Blip_Buffer::count_samples( blip_time_t t ) const
{
unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
return (long) (last_sample - first_sample);
}
blip_time_t Blip_Buffer::count_clocks( long count ) const
{
if ( !factor_ )
return 0;
if ( count > buffer_size_ )
count = buffer_size_;
blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
offset_ -= (uint64_t) count << BLIP_BUFFER_ACCURACY;
}
void Blip_Buffer::remove_samples( long count )
@ -161,10 +142,10 @@ Blip_Synth_Fast_::Blip_Synth_Fast_()
void Blip_Synth_Fast_::volume_unit( double new_unit )
{
delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
delta_factor = (int)(new_unit * (1L << BLIP_SAMPLE_BITS) + 0.5);
}
long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_samples, int stereo )
long Blip_Buffer::read_samples( int16_t* BLIP_RESTRICT out, long max_samples)
{
long count = samples_avail();
if ( count > max_samples )
@ -175,30 +156,14 @@ long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_sampl
int const bass = BLIP_READER_BASS( *this );
BLIP_READER_BEGIN( reader, *this );
#ifndef WANT_STEREO_SOUND
if ( !stereo )
for ( int32_t n = count; n; --n )
{
for ( blip_long n = count; n; --n )
{
blip_long s = BLIP_READER_READ( reader );
if ( (blip_sample_t) s != s )
s = 0x7FFF - (s >> 24);
*out++ = (blip_sample_t) s;
BLIP_READER_NEXT( reader, bass );
}
}
else
#endif
{
for ( blip_long n = count; n; --n )
{
blip_long s = BLIP_READER_READ( reader );
if ( (blip_sample_t) s != s )
s = 0x7FFF - (s >> 24);
*out = (blip_sample_t) s;
out += 2;
BLIP_READER_NEXT( reader, bass );
}
int32_t s = BLIP_READER_READ( reader );
if ( (int16_t) s != s )
s = 0x7FFF - (s >> 24);
*out = (int16_t) s;
out += 2;
BLIP_READER_NEXT( reader, bass );
}
BLIP_READER_END( reader, *this );
@ -206,20 +171,3 @@ long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long max_sampl
}
return count;
}
void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
{
buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
int const sample_shift = blip_sample_bits - 16;
int prev = 0;
while ( count-- )
{
blip_long s = (blip_long) *in++ << sample_shift;
*out += s - prev;
prev = s;
++out;
}
*out -= prev;
}

View File

@ -22,10 +22,8 @@ Stereo_Buffer::~Stereo_Buffer() {
bool Stereo_Buffer::set_sample_rate( long rate, int msec )
{
for ( int i = 0; i < buf_count; i++ ) {
if ( bufs [i].set_sample_rate( rate, msec ) )
{
if ( bufs [i].set_sample_rate( rate, msec ) == -1)
return false;
}
}
return true;
@ -51,18 +49,16 @@ void Stereo_Buffer::clear()
bufs [i].clear();
}
void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo )
void Stereo_Buffer::end_frame(int32_t clock_count)
{
for ( unsigned i = 0; i < buf_count; i++ )
{
bufs [i].end_frame( clock_count );
}
stereo_added |= stereo;
stereo_added = true;
}
long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
long Stereo_Buffer::read_samples( int16_t *out, long max_samples )
{
long count = bufs [0].samples_avail();
if ( count > max_samples / 2 )
@ -77,17 +73,6 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
bufs [1].remove_samples( count );
bufs [2].remove_samples( count );
}
#ifndef WANT_STEREO_SOUND
else
{
mix_mono( out, count );
bufs [0].remove_samples( count );
bufs [1].remove_silence( count );
bufs [2].remove_silence( count );
}
#endif
// to do: this might miss opportunities for optimization
if ( !bufs [0].samples_avail() ) {
@ -99,7 +84,7 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
return count * 2;
}
void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
void Stereo_Buffer::mix_stereo( int16_t *out, long count )
{
Blip_Reader left;
Blip_Reader right;
@ -125,67 +110,3 @@ void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
right.end( bufs [2] );
left.end( bufs [1] );
}
void Stereo_Buffer::mix_stereo( float* out, long count )
{
Blip_Reader left;
Blip_Reader right;
Blip_Reader center;
left.begin( bufs [1] );
right.begin( bufs [2] );
int bass = center.begin( bufs [0] );
while ( count-- )
{
int c = center.read();
out [0] = (float)(c + left.read()) / 32768;
out [1] = (float)(c + right.read()) / 32768;
out += 2;
center.next( bass );
left.next( bass );
right.next( bass );
}
center.end( bufs [0] );
right.end( bufs [2] );
left.end( bufs [1] );
}
#ifndef WANT_STEREO_SOUND
void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
{
Blip_Reader in;
int bass = in.begin( bufs [0] );
while ( count-- )
{
int sample = in.read();
out [0] = sample;
out [1] = sample;
out += 2;
in.next( bass );
}
in.end( bufs [0] );
}
void Stereo_Buffer::mix_mono( float* out, long count )
{
Blip_Reader in;
int bass = in.begin( bufs [0] );
while ( count-- )
{
int sample = in.read();
out [0] = (float)(sample) / 32768;
out [1] = (float)(sample) / 32768;
out += 2;
in.next( bass );
}
in.end( bufs [0] );
}
#endif