[GSF] Copied a few things from kode54's viogsf.
--- a/src/in_gsf/vbam/apu/Blip_Buffer.cpp
+++ b/src/in_gsf/vbam/apu/Blip_Buffer.cpp
@@ -60,7 +60,7 @@
}
}
-void Blip_Buffer::set_sample_rate(long new_rate, int msec)
+void Blip_Buffer::set_sample_rate(long new_rate, long msec)
{
// start with maximum length that resampled time can represent
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64;
@@ -372,7 +372,7 @@
auto out = &this->buffer_[(this->offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2];
static const int sample_shift = blip_sample_bits - 16;
- int prev = 0;
+ int32_t prev = 0;
while (count--)
{
int32_t s = static_cast<int32_t>(*in++) << sample_shift;
--- a/src/in_gsf/vbam/apu/Blip_Buffer.h
+++ b/src/in_gsf/vbam/apu/Blip_Buffer.h
@@ -19,7 +19,7 @@
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer
// untouched and returns "Out of memory", otherwise returns NULL.
- void set_sample_rate(long samples_per_sec, int msec_length = 250);
+ void set_sample_rate(long samples_per_sec, long msec_length = 250);
// Sets number of source time units per second
void clock_rate(long clocks_per_sec);
@@ -54,7 +54,7 @@
long sample_rate() const;
// Length of buffer in milliseconds
- int length() const;
+ int32_t length() const;
// Number of source time units per second
long clock_rate() const;
@@ -107,7 +107,7 @@
long sample_rate_;
long clock_rate_;
int bass_freq_;
- int length_;
+ int32_t length_;
Blip_Buffer *modified_; // non-zero = true (more optimal than using bool, heh)
};
@@ -421,7 +421,7 @@
inline blip_eq_t::blip_eq_t(double t) : treble(t), rolloff_freq(0), sample_rate(44100), cutoff_freq(0) { }
inline blip_eq_t::blip_eq_t(double t, long rf, long sr, long cf) : treble(t), rolloff_freq(rf), sample_rate(sr), cutoff_freq(cf) { }
-inline int Blip_Buffer::length() const { return this->length_; }
+inline int32_t Blip_Buffer::length() const { return this->length_; }
inline long Blip_Buffer::samples_avail() const { return static_cast<long>(this->offset_ >> BLIP_BUFFER_ACCURACY); }
inline long Blip_Buffer::sample_rate() const { return this->sample_rate_; }
inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
--- a/src/in_gsf/vbam/apu/Gb_Apu.cpp
+++ b/src/in_gsf/vbam/apu/Gb_Apu.cpp
@@ -24,7 +24,8 @@
void Gb_Apu::treble_eq(const blip_eq_t &eq)
{
this->good_synth.treble_eq(eq);
- this->med_synth.treble_eq(eq);
+ this->med_synth[0].treble_eq(eq);
+ this->med_synth[1].treble_eq(eq);
}
int Gb_Apu::calc_output(int osc) const
@@ -57,7 +58,8 @@
{
double v = this->volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv;
this->good_synth.volume(v);
- this->med_synth.volume(v);
+ this->med_synth[0].volume(v);
+ this->med_synth[1].volume(v * 1.4);
}
void Gb_Apu::apply_volume()
@@ -174,7 +176,7 @@
o.regs = &this->regs[i * 5];
o.output = o.outputs[0] = o.outputs[1] = o.outputs[2] = o.outputs[3] = nullptr;
o.good_synth = &this->good_synth;
- o.med_synth = &this->med_synth;
+ o.med_synth = &this->med_synth[i == 3 ? 1 : 0];
}
this->reduce_clicks_ = false;
@@ -255,7 +257,7 @@
if (o.output)
{
o.output->set_modified();
- this->med_synth.offset(this->last_time, delta, o.output);
+ this->med_synth[0].offset(this->last_time, delta, o.output);
}
}
}
--- a/src/in_gsf/vbam/apu/Gb_Apu.h
+++ b/src/in_gsf/vbam/apu/Gb_Apu.h
@@ -101,7 +101,7 @@
// large objects after everything else
Gb_Osc::Good_Synth good_synth;
- Gb_Osc::Med_Synth med_synth;
+ Gb_Osc::Med_Synth med_synth[2];
void reset_lengths();
void reset_regs();
--- a/src/in_gsf/vbam/apu/Gb_Oscs.cpp
+++ b/src/in_gsf/vbam/apu/Gb_Oscs.cpp
@@ -373,7 +373,7 @@
if (!vol)
{
// Maintain phase when not playing
- int count = (end_time - time + per - 1) / per;
+ int32_t count = (end_time - time + per - 1) / per;
ph += count; // will be masked below
time += static_cast<blip_time_t>(count) * per;
}
@@ -402,7 +402,7 @@
// Quickly runs LFSR for a large number of clocks. For use when noise is generating
// no sound.
-static unsigned run_lfsr(unsigned s, unsigned mask, int count)
+static unsigned run_lfsr(unsigned s, unsigned mask, int32_t count)
{
static const bool optimized = true; // set to false to use only unoptimized loop in middle
@@ -513,11 +513,11 @@
// Run timer and calculate time of next LFSR clock
static const uint8_t period1s[] = { 1, 2, 4, 6, 8, 10, 12, 14 };
int period1 = period1s[this->regs[3] & 7] * clk_mul;
- int extra = (end_time - time) - this->delay;
+ int32_t extra = (end_time - time) - this->delay;
int per2 = this->period2();
time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1;
- int count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
+ int32_t count = extra < 0 ? 0 : (extra + period1 - 1) / period1;
this->divider = (this->divider - count) & period2_mask;
this->delay = count * period1 - extra;
@@ -533,7 +533,7 @@
else if (!vol)
{
// Maintain phase when not playing
- int count = (end_time - time + per - 1) / per;
+ int32_t count = (end_time - time + per - 1) / per;
time += static_cast<blip_time_t>(count) * per;
bits = run_lfsr(bits, ~mask, count);
}
@@ -618,7 +618,7 @@
if (!playing)
{
// Maintain phase when not playing
- int count = (end_time - time + per - 1) / per;
+ int32_t count = (end_time - time + per - 1) / per;
ph += count; // will be masked below
time += static_cast<blip_time_t>(count) * per;
}
--- a/src/in_gsf/vbam/apu/Gb_Oscs.h
+++ b/src/in_gsf/vbam/apu/Gb_Oscs.h
@@ -37,7 +37,7 @@
const Good_Synth *good_synth;
const Med_Synth *med_synth;
- int delay; // clocks until frequency timer expires
+ int32_t delay; // clocks until frequency timer expires
int length_ctr; // length counter
unsigned phase; // waveform phase (or equivalent)
bool enabled; // internal enabled flag
--- a/src/in_gsf/vbam/apu/Multi_Buffer.cpp
+++ b/src/in_gsf/vbam/apu/Multi_Buffer.cpp
@@ -94,7 +94,7 @@
Stereo_Buffer::~Stereo_Buffer() { }
-void Stereo_Buffer::set_sample_rate(long rate, int msec)
+void Stereo_Buffer::set_sample_rate(long rate, long msec)
{
this->mixer.samples_read = 0;
for (int i = bufs_size; --i >= 0; )
--- a/src/in_gsf/vbam/apu/Multi_Buffer.h
+++ b/src/in_gsf/vbam/apu/Multi_Buffer.h
@@ -31,14 +31,14 @@
virtual channel_t channel(int index);
// See Blip_Buffer.h
- virtual void set_sample_rate(long rate, int msec = blip_default_length);
+ virtual void set_sample_rate(long rate, long msec = blip_default_length);
virtual void clock_rate(long) { }
virtual void bass_freq(int) { }
virtual void clear() { }
long sample_rate() const;
// Length of buffer, in milliseconds
- int length() const;
+ int32_t length() const;
// See Blip_Buffer.h
virtual void end_frame(blip_time_t) { }
@@ -66,7 +66,7 @@
unsigned channels_changed_count_;
long sample_rate_;
- int length_;
+ int32_t length_;
int channel_count_;
const int samples_per_frame_;
const int *channel_types_;
@@ -115,7 +115,7 @@
Stereo_Buffer();
~Stereo_Buffer();
- void set_sample_rate(long, int msec = blip_default_length);
+ void set_sample_rate(long, long msec = blip_default_length);
void clock_rate(long);
void bass_freq(int);
void clear();
@@ -134,7 +134,7 @@
long samples_avail_;
};
-inline void Multi_Buffer::set_sample_rate(long rate, int msec)
+inline void Multi_Buffer::set_sample_rate(long rate, long msec)
{
this->sample_rate_ = rate;
this->length_ = msec;
@@ -144,7 +144,7 @@
inline long Multi_Buffer::sample_rate() const { return this->sample_rate_; }
-inline int Multi_Buffer::length() const { return this->length_; }
+inline int32_t Multi_Buffer::length() const { return this->length_; }
inline void Multi_Buffer::set_channel_count(int n, const int *types)
{
--- a/src/in_gsf/vbam/gba/Sound.cpp
+++ b/src/in_gsf/vbam/gba/Sound.cpp
@@ -115,7 +115,7 @@
if (soundInterpolation)
{
// base filtering on how long since last sample was output
- int period = time - this->last_time;
+ int32_t period = time - this->last_time;
int idx = period / 512;
if (idx >= 3)
@@ -158,7 +158,7 @@
if (soundInterpolation)
{
// base filtering on how long since last sample was output
- int period = time - this->last_time;
+ int32_t period = time - this->last_time;
int idx = period / 512;
if (idx >= 3)
@@ -350,22 +350,21 @@
// that don't use the length parameter of the write method.
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the
// samples at once to help reducing the audio delay on all platforms.
- int soundBufferLen = (soundSampleRate / 60) * 4;
+ int32_t soundBufferLen = (soundSampleRate / 60) * 4;
// soundBufferLen should have a whole number of sample pairs
assert(!(soundBufferLen % (2 * sizeof(*soundFinalWave))));
// number of samples in output buffer
- int out_buf_size = soundBufferLen / sizeof(*soundFinalWave);
-
- // Keep filling and writing soundFinalWave until it can't be fully filled
- while (buffer->samples_avail() >= out_buf_size)
- {
- buffer->read_samples(reinterpret_cast<blip_sample_t *>(soundFinalWave), out_buf_size);
+ int32_t out_buf_size = soundBufferLen / sizeof(*soundFinalWave);
+
+ while (buffer->samples_avail())
+ {
+ long samples_read = buffer->read_samples(reinterpret_cast<blip_sample_t *>(soundFinalWave), out_buf_size);
if (soundPaused)
soundResume();
- soundDriver->write(soundFinalWave, soundBufferLen);
+ soundDriver->write(soundFinalWave, samples_read * sizeof(*soundFinalWave));
}
}
@@ -374,11 +373,11 @@
soundFiltering_ = soundFiltering;
int base_freq = static_cast<int>(32768 - soundFiltering_ * 16384);
- int nyquist = stereo_buffer->sample_rate() / 2;
+ int32_t nyquist = stereo_buffer->sample_rate() / 2;
for (int i = 0; i < 3; ++i)
{
- int cutoff = base_freq >> i;
+ int32_t cutoff = base_freq >> i;
if (cutoff > nyquist)
cutoff = nyquist;
pcm_synth[i].treble_eq(blip_eq_t(0, 0, stereo_buffer->sample_rate(), cutoff));
@@ -400,8 +399,6 @@
if (soundVolume_ != soundVolume)
apply_volume();
}
-
- ioMem[NR52] = (ioMem[NR52] & 0x80) | (gb_apu->read_status() & 0x7f);
}
static void apply_muting()
@@ -423,8 +420,11 @@
static void reset_apu()
{
- gb_apu->reduce_clicks(true);
- gb_apu->reset(gb_apu->mode_agb, true);
+ if (gb_apu)
+ {
+ gb_apu->reduce_clicks(true);
+ gb_apu->reset(Gb_Apu::mode_agb, true);
+ }
if (stereo_buffer)
stereo_buffer->clear();
@@ -438,23 +438,24 @@
pcm[0].pcm.init();
pcm[1].pcm.init();
- // APU
- if (!gb_apu)
- {
- gb_apu.reset(new Gb_Apu); // TODO: handle out of memory
- reset_apu();
- }
-
// Stereo_Buffer
stereo_buffer.reset(new Stereo_Buffer); // TODO: handle out of memory
stereo_buffer->set_sample_rate(soundSampleRate); // TODO: handle out of memory
- stereo_buffer->clock_rate(gb_apu->clock_rate);
// PCM
pcm[0].which = 0;
pcm[1].which = 1;
apply_filtering();
+ // APU
+ if (!gb_apu)
+ {
+ gb_apu.reset(new Gb_Apu); // TODO: handle out of memory
+ reset_apu();
+ gb_apu->treble_eq(blip_eq_t(0, 0, soundSampleRate, soundSampleRate / 2));
+ }
+ stereo_buffer->clock_rate(gb_apu->clock_rate);
+
// Volume Level
apply_muting();
apply_volume();