| ... | ... |
@@ -60,7 +60,7 @@ void Blip_Buffer::clear(int entire_buffer) |
| 60 | 60 |
} |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-void Blip_Buffer::set_sample_rate(long new_rate, int msec) |
|
| 63 |
+void Blip_Buffer::set_sample_rate(long new_rate, long msec) |
|
| 64 | 64 |
{
|
| 65 | 65 |
// start with maximum length that resampled time can represent |
| 66 | 66 |
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - blip_buffer_extra_ - 64; |
| ... | ... |
@@ -372,7 +372,7 @@ void Blip_Buffer::mix_samples(const blip_sample_t *in, long count) |
| 372 | 372 |
auto out = &this->buffer_[(this->offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2]; |
| 373 | 373 |
|
| 374 | 374 |
static const int sample_shift = blip_sample_bits - 16; |
| 375 |
- int prev = 0; |
|
| 375 |
+ int32_t prev = 0; |
|
| 376 | 376 |
while (count--) |
| 377 | 377 |
{
|
| 378 | 378 |
int32_t s = static_cast<int32_t>(*in++) << sample_shift; |
| ... | ... |
@@ -19,7 +19,7 @@ public: |
| 19 | 19 |
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
| 20 | 20 |
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
| 21 | 21 |
// untouched and returns "Out of memory", otherwise returns NULL. |
| 22 |
- void set_sample_rate(long samples_per_sec, int msec_length = 250); |
|
| 22 |
+ void set_sample_rate(long samples_per_sec, long msec_length = 250); |
|
| 23 | 23 |
|
| 24 | 24 |
// Sets number of source time units per second |
| 25 | 25 |
void clock_rate(long clocks_per_sec); |
| ... | ... |
@@ -54,7 +54,7 @@ public: |
| 54 | 54 |
long sample_rate() const; |
| 55 | 55 |
|
| 56 | 56 |
// Length of buffer in milliseconds |
| 57 |
- int length() const; |
|
| 57 |
+ int32_t length() const; |
|
| 58 | 58 |
|
| 59 | 59 |
// Number of source time units per second |
| 60 | 60 |
long clock_rate() const; |
| ... | ... |
@@ -107,7 +107,7 @@ private: |
| 107 | 107 |
long sample_rate_; |
| 108 | 108 |
long clock_rate_; |
| 109 | 109 |
int bass_freq_; |
| 110 |
- int length_; |
|
| 110 |
+ int32_t length_; |
|
| 111 | 111 |
Blip_Buffer *modified_; // non-zero = true (more optimal than using bool, heh) |
| 112 | 112 |
}; |
| 113 | 113 |
|
| ... | ... |
@@ -421,7 +421,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::update( |
| 421 | 421 |
inline blip_eq_t::blip_eq_t(double t) : treble(t), rolloff_freq(0), sample_rate(44100), cutoff_freq(0) { }
|
| 422 | 422 |
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) { }
|
| 423 | 423 |
|
| 424 |
-inline int Blip_Buffer::length() const { return this->length_; }
|
|
| 424 |
+inline int32_t Blip_Buffer::length() const { return this->length_; }
|
|
| 425 | 425 |
inline long Blip_Buffer::samples_avail() const { return static_cast<long>(this->offset_ >> BLIP_BUFFER_ACCURACY); }
|
| 426 | 426 |
inline long Blip_Buffer::sample_rate() const { return this->sample_rate_; }
|
| 427 | 427 |
inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
| ... | ... |
@@ -24,7 +24,8 @@ static const int power_mask = 0x80; |
| 24 | 24 |
void Gb_Apu::treble_eq(const blip_eq_t &eq) |
| 25 | 25 |
{
|
| 26 | 26 |
this->good_synth.treble_eq(eq); |
| 27 |
- this->med_synth.treble_eq(eq); |
|
| 27 |
+ this->med_synth[0].treble_eq(eq); |
|
| 28 |
+ this->med_synth[1].treble_eq(eq); |
|
| 28 | 29 |
} |
| 29 | 30 |
|
| 30 | 31 |
int Gb_Apu::calc_output(int osc) const |
| ... | ... |
@@ -57,7 +58,8 @@ void Gb_Apu::synth_volume(int iv) |
| 57 | 58 |
{
|
| 58 | 59 |
double v = this->volume_ * 0.60 / osc_count / 15 /*steps*/ / 8 /*master vol range*/ * iv; |
| 59 | 60 |
this->good_synth.volume(v); |
| 60 |
- this->med_synth.volume(v); |
|
| 61 |
+ this->med_synth[0].volume(v); |
|
| 62 |
+ this->med_synth[1].volume(v * 1.4); |
|
| 61 | 63 |
} |
| 62 | 64 |
|
| 63 | 65 |
void Gb_Apu::apply_volume() |
| ... | ... |
@@ -174,7 +176,7 @@ Gb_Apu::Gb_Apu() |
| 174 | 176 |
o.regs = &this->regs[i * 5]; |
| 175 | 177 |
o.output = o.outputs[0] = o.outputs[1] = o.outputs[2] = o.outputs[3] = nullptr; |
| 176 | 178 |
o.good_synth = &this->good_synth; |
| 177 |
- o.med_synth = &this->med_synth; |
|
| 179 |
+ o.med_synth = &this->med_synth[i == 3 ? 1 : 0]; |
|
| 178 | 180 |
} |
| 179 | 181 |
|
| 180 | 182 |
this->reduce_clicks_ = false; |
| ... | ... |
@@ -255,7 +257,7 @@ void Gb_Apu::silence_osc(Gb_Osc &o) |
| 255 | 257 |
if (o.output) |
| 256 | 258 |
{
|
| 257 | 259 |
o.output->set_modified(); |
| 258 |
- this->med_synth.offset(this->last_time, delta, o.output); |
|
| 260 |
+ this->med_synth[0].offset(this->last_time, delta, o.output); |
|
| 259 | 261 |
} |
| 260 | 262 |
} |
| 261 | 263 |
} |
| ... | ... |
@@ -373,7 +373,7 @@ void Gb_Square::run(blip_time_t time, blip_time_t end_time) |
| 373 | 373 |
if (!vol) |
| 374 | 374 |
{
|
| 375 | 375 |
// Maintain phase when not playing |
| 376 |
- int count = (end_time - time + per - 1) / per; |
|
| 376 |
+ int32_t count = (end_time - time + per - 1) / per; |
|
| 377 | 377 |
ph += count; // will be masked below |
| 378 | 378 |
time += static_cast<blip_time_t>(count) * per; |
| 379 | 379 |
} |
| ... | ... |
@@ -402,7 +402,7 @@ void Gb_Square::run(blip_time_t time, blip_time_t end_time) |
| 402 | 402 |
|
| 403 | 403 |
// Quickly runs LFSR for a large number of clocks. For use when noise is generating |
| 404 | 404 |
// no sound. |
| 405 |
-static unsigned run_lfsr(unsigned s, unsigned mask, int count) |
|
| 405 |
+static unsigned run_lfsr(unsigned s, unsigned mask, int32_t count) |
|
| 406 | 406 |
{
|
| 407 | 407 |
static const bool optimized = true; // set to false to use only unoptimized loop in middle |
| 408 | 408 |
|
| ... | ... |
@@ -513,11 +513,11 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time) |
| 513 | 513 |
// Run timer and calculate time of next LFSR clock |
| 514 | 514 |
static const uint8_t period1s[] = { 1, 2, 4, 6, 8, 10, 12, 14 };
|
| 515 | 515 |
int period1 = period1s[this->regs[3] & 7] * clk_mul; |
| 516 |
- int extra = (end_time - time) - this->delay; |
|
| 516 |
+ int32_t extra = (end_time - time) - this->delay; |
|
| 517 | 517 |
int per2 = this->period2(); |
| 518 | 518 |
time += this->delay + ((this->divider ^ (per2 >> 1)) & (per2 - 1)) * period1; |
| 519 | 519 |
|
| 520 |
- int count = extra < 0 ? 0 : (extra + period1 - 1) / period1; |
|
| 520 |
+ int32_t count = extra < 0 ? 0 : (extra + period1 - 1) / period1; |
|
| 521 | 521 |
this->divider = (this->divider - count) & period2_mask; |
| 522 | 522 |
this->delay = count * period1 - extra; |
| 523 | 523 |
|
| ... | ... |
@@ -533,7 +533,7 @@ void Gb_Noise::run(blip_time_t time, blip_time_t end_time) |
| 533 | 533 |
else if (!vol) |
| 534 | 534 |
{
|
| 535 | 535 |
// Maintain phase when not playing |
| 536 |
- int count = (end_time - time + per - 1) / per; |
|
| 536 |
+ int32_t count = (end_time - time + per - 1) / per; |
|
| 537 | 537 |
time += static_cast<blip_time_t>(count) * per; |
| 538 | 538 |
bits = run_lfsr(bits, ~mask, count); |
| 539 | 539 |
} |
| ... | ... |
@@ -618,7 +618,7 @@ void Gb_Wave::run(blip_time_t time, blip_time_t end_time) |
| 618 | 618 |
if (!playing) |
| 619 | 619 |
{
|
| 620 | 620 |
// Maintain phase when not playing |
| 621 |
- int count = (end_time - time + per - 1) / per; |
|
| 621 |
+ int32_t count = (end_time - time + per - 1) / per; |
|
| 622 | 622 |
ph += count; // will be masked below |
| 623 | 623 |
time += static_cast<blip_time_t>(count) * per; |
| 624 | 624 |
} |
| ... | ... |
@@ -37,7 +37,7 @@ public: |
| 37 | 37 |
const Good_Synth *good_synth; |
| 38 | 38 |
const Med_Synth *med_synth; |
| 39 | 39 |
|
| 40 |
- int delay; // clocks until frequency timer expires |
|
| 40 |
+ int32_t delay; // clocks until frequency timer expires |
|
| 41 | 41 |
int length_ctr; // length counter |
| 42 | 42 |
unsigned phase; // waveform phase (or equivalent) |
| 43 | 43 |
bool enabled; // internal enabled flag |
| ... | ... |
@@ -94,7 +94,7 @@ Stereo_Buffer::Stereo_Buffer() : Multi_Buffer(2) |
| 94 | 94 |
|
| 95 | 95 |
Stereo_Buffer::~Stereo_Buffer() { }
|
| 96 | 96 |
|
| 97 |
-void Stereo_Buffer::set_sample_rate(long rate, int msec) |
|
| 97 |
+void Stereo_Buffer::set_sample_rate(long rate, long msec) |
|
| 98 | 98 |
{
|
| 99 | 99 |
this->mixer.samples_read = 0; |
| 100 | 100 |
for (int i = bufs_size; --i >= 0; ) |
| ... | ... |
@@ -31,14 +31,14 @@ public: |
| 31 | 31 |
virtual channel_t channel(int index); |
| 32 | 32 |
|
| 33 | 33 |
// See Blip_Buffer.h |
| 34 |
- virtual void set_sample_rate(long rate, int msec = blip_default_length); |
|
| 34 |
+ virtual void set_sample_rate(long rate, long msec = blip_default_length); |
|
| 35 | 35 |
virtual void clock_rate(long) { }
|
| 36 | 36 |
virtual void bass_freq(int) { }
|
| 37 | 37 |
virtual void clear() { }
|
| 38 | 38 |
long sample_rate() const; |
| 39 | 39 |
|
| 40 | 40 |
// Length of buffer, in milliseconds |
| 41 |
- int length() const; |
|
| 41 |
+ int32_t length() const; |
|
| 42 | 42 |
|
| 43 | 43 |
// See Blip_Buffer.h |
| 44 | 44 |
virtual void end_frame(blip_time_t) { }
|
| ... | ... |
@@ -66,7 +66,7 @@ private: |
| 66 | 66 |
|
| 67 | 67 |
unsigned channels_changed_count_; |
| 68 | 68 |
long sample_rate_; |
| 69 |
- int length_; |
|
| 69 |
+ int32_t length_; |
|
| 70 | 70 |
int channel_count_; |
| 71 | 71 |
const int samples_per_frame_; |
| 72 | 72 |
const int *channel_types_; |
| ... | ... |
@@ -115,7 +115,7 @@ public: |
| 115 | 115 |
|
| 116 | 116 |
Stereo_Buffer(); |
| 117 | 117 |
~Stereo_Buffer(); |
| 118 |
- void set_sample_rate(long, int msec = blip_default_length); |
|
| 118 |
+ void set_sample_rate(long, long msec = blip_default_length); |
|
| 119 | 119 |
void clock_rate(long); |
| 120 | 120 |
void bass_freq(int); |
| 121 | 121 |
void clear(); |
| ... | ... |
@@ -134,7 +134,7 @@ private: |
| 134 | 134 |
long samples_avail_; |
| 135 | 135 |
}; |
| 136 | 136 |
|
| 137 |
-inline void Multi_Buffer::set_sample_rate(long rate, int msec) |
|
| 137 |
+inline void Multi_Buffer::set_sample_rate(long rate, long msec) |
|
| 138 | 138 |
{
|
| 139 | 139 |
this->sample_rate_ = rate; |
| 140 | 140 |
this->length_ = msec; |
| ... | ... |
@@ -144,7 +144,7 @@ inline int Multi_Buffer::samples_per_frame() const { return this->samples_per_fr
|
| 144 | 144 |
|
| 145 | 145 |
inline long Multi_Buffer::sample_rate() const { return this->sample_rate_; }
|
| 146 | 146 |
|
| 147 |
-inline int Multi_Buffer::length() const { return this->length_; }
|
|
| 147 |
+inline int32_t Multi_Buffer::length() const { return this->length_; }
|
|
| 148 | 148 |
|
| 149 | 149 |
inline void Multi_Buffer::set_channel_count(int n, const int *types) |
| 150 | 150 |
{
|
| ... | ... |
@@ -115,7 +115,7 @@ void Gba_Pcm::apply_control(int idx) |
| 115 | 115 |
if (soundInterpolation) |
| 116 | 116 |
{
|
| 117 | 117 |
// base filtering on how long since last sample was output |
| 118 |
- int period = time - this->last_time; |
|
| 118 |
+ int32_t period = time - this->last_time; |
|
| 119 | 119 |
|
| 120 | 120 |
int idx = period / 512; |
| 121 | 121 |
if (idx >= 3) |
| ... | ... |
@@ -158,7 +158,7 @@ void Gba_Pcm::update(int dac) |
| 158 | 158 |
if (soundInterpolation) |
| 159 | 159 |
{
|
| 160 | 160 |
// base filtering on how long since last sample was output |
| 161 |
- int period = time - this->last_time; |
|
| 161 |
+ int32_t period = time - this->last_time; |
|
| 162 | 162 |
|
| 163 | 163 |
int idx = period / 512; |
| 164 | 164 |
if (idx >= 3) |
| ... | ... |
@@ -350,22 +350,21 @@ void flush_samples(Multi_Buffer *buffer) |
| 350 | 350 |
// that don't use the length parameter of the write method. |
| 351 | 351 |
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the |
| 352 | 352 |
// samples at once to help reducing the audio delay on all platforms. |
| 353 |
- int soundBufferLen = (soundSampleRate / 60) * 4; |
|
| 353 |
+ int32_t soundBufferLen = (soundSampleRate / 60) * 4; |
|
| 354 | 354 |
|
| 355 | 355 |
// soundBufferLen should have a whole number of sample pairs |
| 356 | 356 |
assert(!(soundBufferLen % (2 * sizeof(*soundFinalWave)))); |
| 357 | 357 |
|
| 358 | 358 |
// number of samples in output buffer |
| 359 |
- int out_buf_size = soundBufferLen / sizeof(*soundFinalWave); |
|
| 359 |
+ int32_t out_buf_size = soundBufferLen / sizeof(*soundFinalWave); |
|
| 360 | 360 |
|
| 361 |
- // Keep filling and writing soundFinalWave until it can't be fully filled |
|
| 362 |
- while (buffer->samples_avail() >= out_buf_size) |
|
| 361 |
+ while (buffer->samples_avail()) |
|
| 363 | 362 |
{
|
| 364 |
- buffer->read_samples(reinterpret_cast<blip_sample_t *>(soundFinalWave), out_buf_size); |
|
| 363 |
+ long samples_read = buffer->read_samples(reinterpret_cast<blip_sample_t *>(soundFinalWave), out_buf_size); |
|
| 365 | 364 |
if (soundPaused) |
| 366 | 365 |
soundResume(); |
| 367 | 366 |
|
| 368 |
- soundDriver->write(soundFinalWave, soundBufferLen); |
|
| 367 |
+ soundDriver->write(soundFinalWave, samples_read * sizeof(*soundFinalWave)); |
|
| 369 | 368 |
} |
| 370 | 369 |
} |
| 371 | 370 |
|
| ... | ... |
@@ -374,11 +373,11 @@ static void apply_filtering() |
| 374 | 373 |
soundFiltering_ = soundFiltering; |
| 375 | 374 |
|
| 376 | 375 |
int base_freq = static_cast<int>(32768 - soundFiltering_ * 16384); |
| 377 |
- int nyquist = stereo_buffer->sample_rate() / 2; |
|
| 376 |
+ int32_t nyquist = stereo_buffer->sample_rate() / 2; |
|
| 378 | 377 |
|
| 379 | 378 |
for (int i = 0; i < 3; ++i) |
| 380 | 379 |
{
|
| 381 |
- int cutoff = base_freq >> i; |
|
| 380 |
+ int32_t cutoff = base_freq >> i; |
|
| 382 | 381 |
if (cutoff > nyquist) |
| 383 | 382 |
cutoff = nyquist; |
| 384 | 383 |
pcm_synth[i].treble_eq(blip_eq_t(0, 0, stereo_buffer->sample_rate(), cutoff)); |
| ... | ... |
@@ -400,8 +399,6 @@ void psoundTickfn() |
| 400 | 399 |
if (soundVolume_ != soundVolume) |
| 401 | 400 |
apply_volume(); |
| 402 | 401 |
} |
| 403 |
- |
|
| 404 |
- ioMem[NR52] = (ioMem[NR52] & 0x80) | (gb_apu->read_status() & 0x7f); |
|
| 405 | 402 |
} |
| 406 | 403 |
|
| 407 | 404 |
static void apply_muting() |
| ... | ... |
@@ -423,8 +420,11 @@ static void apply_muting() |
| 423 | 420 |
|
| 424 | 421 |
static void reset_apu() |
| 425 | 422 |
{
|
| 426 |
- gb_apu->reduce_clicks(true); |
|
| 427 |
- gb_apu->reset(gb_apu->mode_agb, true); |
|
| 423 |
+ if (gb_apu) |
|
| 424 |
+ {
|
|
| 425 |
+ gb_apu->reduce_clicks(true); |
|
| 426 |
+ gb_apu->reset(Gb_Apu::mode_agb, true); |
|
| 427 |
+ } |
|
| 428 | 428 |
|
| 429 | 429 |
if (stereo_buffer) |
| 430 | 430 |
stereo_buffer->clear(); |
| ... | ... |
@@ -438,23 +438,24 @@ static void remake_stereo_buffer() |
| 438 | 438 |
pcm[0].pcm.init(); |
| 439 | 439 |
pcm[1].pcm.init(); |
| 440 | 440 |
|
| 441 |
- // APU |
|
| 442 |
- if (!gb_apu) |
|
| 443 |
- {
|
|
| 444 |
- gb_apu.reset(new Gb_Apu); // TODO: handle out of memory |
|
| 445 |
- reset_apu(); |
|
| 446 |
- } |
|
| 447 |
- |
|
| 448 | 441 |
// Stereo_Buffer |
| 449 | 442 |
stereo_buffer.reset(new Stereo_Buffer); // TODO: handle out of memory |
| 450 | 443 |
stereo_buffer->set_sample_rate(soundSampleRate); // TODO: handle out of memory |
| 451 |
- stereo_buffer->clock_rate(gb_apu->clock_rate); |
|
| 452 | 444 |
|
| 453 | 445 |
// PCM |
| 454 | 446 |
pcm[0].which = 0; |
| 455 | 447 |
pcm[1].which = 1; |
| 456 | 448 |
apply_filtering(); |
| 457 | 449 |
|
| 450 |
+ // APU |
|
| 451 |
+ if (!gb_apu) |
|
| 452 |
+ {
|
|
| 453 |
+ gb_apu.reset(new Gb_Apu); // TODO: handle out of memory |
|
| 454 |
+ reset_apu(); |
|
| 455 |
+ gb_apu->treble_eq(blip_eq_t(0, 0, soundSampleRate, soundSampleRate / 2)); |
|
| 456 |
+ } |
|
| 457 |
+ stereo_buffer->clock_rate(gb_apu->clock_rate); |
|
| 458 |
+ |
|
| 458 | 459 |
// Volume Level |
| 459 | 460 |
apply_muting(); |
| 460 | 461 |
apply_volume(); |