mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-13 00:25:26 +00:00
Attempts audio output.
This commit is contained in:
@@ -107,8 +107,15 @@ void Audio::output() {
|
|||||||
while(!buffer_available_[buffer_pointer_].load(std::memory_order::memory_order_relaxed));
|
while(!buffer_available_[buffer_pointer_].load(std::memory_order::memory_order_relaxed));
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_[buffer_pointer_][sample_pointer_] = 0;
|
buffer_[buffer_pointer_][sample_pointer_] = int16_t(
|
||||||
++sample_pointer_;
|
(channels_[0].output_level * channels_[0].output_enabled +
|
||||||
|
channels_[2].output_level * channels_[2].output_enabled) << 7
|
||||||
|
);
|
||||||
|
buffer_[buffer_pointer_][sample_pointer_+1] = int16_t(
|
||||||
|
(channels_[1].output_level * channels_[1].output_enabled +
|
||||||
|
channels_[3].output_level * channels_[3].output_enabled) << 7
|
||||||
|
);
|
||||||
|
sample_pointer_ += 2;
|
||||||
|
|
||||||
if(sample_pointer_ == buffer_[buffer_pointer_].size()) {
|
if(sample_pointer_ == buffer_[buffer_pointer_].size()) {
|
||||||
const auto &buffer = buffer_[buffer_pointer_];
|
const auto &buffer = buffer_[buffer_pointer_];
|
||||||
@@ -116,7 +123,7 @@ void Audio::output() {
|
|||||||
|
|
||||||
flag.store(false, std::memory_order::memory_order_release);
|
flag.store(false, std::memory_order::memory_order_release);
|
||||||
queue_.enqueue([this, &buffer, &flag] {
|
queue_.enqueue([this, &buffer, &flag] {
|
||||||
speaker_.push(buffer.data(), buffer.size());
|
speaker_.push(buffer.data(), buffer.size() >> 1);
|
||||||
flag.store(true, std::memory_order::memory_order_relaxed);
|
flag.store(true, std::memory_order::memory_order_relaxed);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -438,7 +445,8 @@ template <> bool Audio::Channel::output<Audio::Channel::State::PlayingHigh>() {
|
|||||||
return transit<State::PlayingHigh, State::PlayingLow>();
|
return transit<State::PlayingHigh, State::PlayingLow>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: penhi (i.e. output high byte).
|
// Output high byte.
|
||||||
|
output_level = data_latch >> 8;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -479,7 +487,8 @@ template <> bool Audio::Channel::output<Audio::Channel::State::PlayingLow>() {
|
|||||||
return transit<State::PlayingLow, State::PlayingHigh>();
|
return transit<State::PlayingLow, State::PlayingHigh>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: not penhi (i.e. output low byte).
|
// Output low byte.
|
||||||
|
output_level = data_latch & 0xff;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -489,6 +498,11 @@ template <> bool Audio::Channel::output<Audio::Channel::State::PlayingLow>() {
|
|||||||
//
|
//
|
||||||
|
|
||||||
bool Audio::Channel::output() {
|
bool Audio::Channel::output() {
|
||||||
|
// Update pulse-width modulation.
|
||||||
|
output_phase = (output_phase + 1) & 63;
|
||||||
|
output_enabled |= !output_phase;
|
||||||
|
output_enabled &= output_phase != volume;
|
||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case State::Disabled: return output<State::Disabled>();
|
case State::Disabled: return output<State::Disabled>();
|
||||||
case State::WaitingForDummyDMA: return output<State::WaitingForDummyDMA>();
|
case State::WaitingForDummyDMA: return output<State::WaitingForDummyDMA>();
|
||||||
|
@@ -103,6 +103,11 @@ class Audio: public DMADevice<4> {
|
|||||||
bool output();
|
bool output();
|
||||||
template <State state> bool output();
|
template <State state> bool output();
|
||||||
template <State begin, State end> bool transit();
|
template <State begin, State end> bool transit();
|
||||||
|
|
||||||
|
// Output state.
|
||||||
|
uint8_t output_level = 0;
|
||||||
|
uint8_t output_phase = 0;
|
||||||
|
bool output_enabled = false;
|
||||||
} channels_[4];
|
} channels_[4];
|
||||||
|
|
||||||
// Transient output state, and its destination.
|
// Transient output state, and its destination.
|
||||||
|
Reference in New Issue
Block a user