mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
It's still interrupt-deficient, but fills in additional Ensoniq audio generation.
This commit is contained in:
parent
8edb3fcd5f
commit
72884f37c3
@ -117,7 +117,7 @@ void GLU::run_for(Cycles cycles) {
|
|||||||
|
|
||||||
void GLU::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
void GLU::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||||
// Update remote state, generating audio.
|
// Update remote state, generating audio.
|
||||||
generate_audio(number_of_samples, target, output_range_);
|
generate_audio(number_of_samples, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLU::skip_samples(const std::size_t number_of_samples) {
|
void GLU::skip_samples(const std::size_t number_of_samples) {
|
||||||
@ -174,12 +174,9 @@ uint8_t GLU::get_address_high() {
|
|||||||
|
|
||||||
// MARK: - Update logic.
|
// MARK: - Update logic.
|
||||||
|
|
||||||
void GLU::generate_audio(size_t number_of_samples, std::int16_t *target, int16_t range) {
|
void GLU::generate_audio(size_t number_of_samples, std::int16_t *target) {
|
||||||
(void)number_of_samples;
|
|
||||||
(void)target;
|
|
||||||
(void)range;
|
|
||||||
|
|
||||||
auto next_store = pending_stores_[pending_store_read_].load(std::memory_order::memory_order_acquire);
|
auto next_store = pending_stores_[pending_store_read_].load(std::memory_order::memory_order_acquire);
|
||||||
|
uint8_t next_amplitude = 255;
|
||||||
for(size_t sample = 0; sample < number_of_samples; sample++) {
|
for(size_t sample = 0; sample < number_of_samples; sample++) {
|
||||||
|
|
||||||
// TODO: there's a bit of a hack here where it is assumed that the input clock has been
|
// TODO: there's a bit of a hack here where it is assumed that the input clock has been
|
||||||
@ -206,13 +203,22 @@ void GLU::generate_audio(size_t number_of_samples, std::int16_t *target, int16_t
|
|||||||
if(remote_.oscillators[c].position & remote_.oscillators[c].overflow_mask) {
|
if(remote_.oscillators[c].position & remote_.oscillators[c].overflow_mask) {
|
||||||
remote_.oscillators[c].position = 0;
|
remote_.oscillators[c].position = 0;
|
||||||
remote_.oscillators[c].control |= 1;
|
remote_.oscillators[c].control |= 1;
|
||||||
} else {
|
|
||||||
output += remote_.oscillators[c].output(remote_.ram_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // Sync/AM mode.
|
case 4: // Sync/AM mode.
|
||||||
assert(false);
|
if(c&1) {
|
||||||
|
// Oscillator is odd-numbered; it will amplitude-modulate the next voice.
|
||||||
|
next_amplitude = remote_.oscillators[c].sample(remote_.ram_);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// Oscillator is even-numbered; it will 'sync' to the even voice, i.e. any
|
||||||
|
// time it wraps around, it will reset the next oscillator.
|
||||||
|
if(remote_.oscillators[c].position & remote_.oscillators[c].overflow_mask) {
|
||||||
|
remote_.oscillators[c].position &= remote_.oscillators[c].overflow_mask;
|
||||||
|
remote_.oscillators[c+1].position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // Swap mode; possibly trigger partner, and update sample.
|
case 6: // Swap mode; possibly trigger partner, and update sample.
|
||||||
@ -223,11 +229,16 @@ void GLU::generate_audio(size_t number_of_samples, std::int16_t *target, int16_t
|
|||||||
remote_.oscillators[c].control |= 1;
|
remote_.oscillators[c].control |= 1;
|
||||||
remote_.oscillators[c].position = 0;
|
remote_.oscillators[c].position = 0;
|
||||||
remote_.oscillators[c^1].control &= ~1;
|
remote_.oscillators[c^1].control &= ~1;
|
||||||
} else {
|
|
||||||
output += remote_.oscillators[c].output(remote_.ram_);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't add output for newly-halted oscillators.
|
||||||
|
if(remote_.oscillators[c].control&1) continue;
|
||||||
|
|
||||||
|
// Append new output.
|
||||||
|
output += (remote_.oscillators[c].output(remote_.ram_) * next_amplitude) / 255;
|
||||||
|
next_amplitude = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximum total output was 32 channels times a 16-bit range. Map that down.
|
// Maximum total output was 32 channels times a 16-bit range. Map that down.
|
||||||
|
@ -94,7 +94,7 @@ class GLU: public Outputs::Speaker::SampleSource {
|
|||||||
|
|
||||||
// Functions to update an EnsoniqState; these don't belong to the state itself
|
// Functions to update an EnsoniqState; these don't belong to the state itself
|
||||||
// because they also access the pending stores (inter alia).
|
// because they also access the pending stores (inter alia).
|
||||||
void generate_audio(size_t number_of_samples, std::int16_t *target, int16_t range);
|
void generate_audio(size_t number_of_samples, std::int16_t *target);
|
||||||
void skip_audio(EnsoniqState &state, size_t number_of_samples);
|
void skip_audio(EnsoniqState &state, size_t number_of_samples);
|
||||||
|
|
||||||
// Audio-thread state.
|
// Audio-thread state.
|
||||||
|
Loading…
Reference in New Issue
Block a user