mirror of
https://github.com/libretro/beetle-ngp-libretro.git
synced 2024-11-22 23:49:40 +00:00
Simplify Blip_Buffer.cpp and Stereo_Buffer.cpp
This commit is contained in:
parent
7b5e21a7d9
commit
778be26770
3
Makefile
3
Makefile
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 :=
|
||||
|
@ -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 ); }
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user