mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Merge pull request #1069 from TomHarte/AsyncTaskQueueRename
Switch name back to emphasise _async_.
This commit is contained in:
commit
9c43470c43
@ -47,7 +47,7 @@ template <typename MachineType> class MultiInterface {
|
|||||||
std::recursive_mutex &machines_mutex_;
|
std::recursive_mutex &machines_mutex_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Concurrency::TaskQueue<true>> queues_;
|
std::vector<Concurrency::AsyncTaskQueue<true>> queues_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MultiTimedMachine: public MultiInterface<MachineTypes::TimedMachine>, public MachineTypes::TimedMachine {
|
class MultiTimedMachine: public MultiInterface<MachineTypes::TimedMachine>, public MachineTypes::TimedMachine {
|
||||||
|
@ -315,7 +315,7 @@ template <class T, class LocalTimeScale = HalfCycles, class TargetTimeScale = Lo
|
|||||||
LocalTimeScale time_since_update_;
|
LocalTimeScale time_since_update_;
|
||||||
TargetTimeScale threshold_;
|
TargetTimeScale threshold_;
|
||||||
bool is_flushed_ = true;
|
bool is_flushed_ = true;
|
||||||
Concurrency::TaskQueue<true> task_queue_;
|
Concurrency::AsyncTaskQueue<true> task_queue_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* JustInTime_h */
|
#endif /* JustInTime_h */
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
using namespace MOS::MOS6560;
|
using namespace MOS::MOS6560;
|
||||||
|
|
||||||
AudioGenerator::AudioGenerator(Concurrency::TaskQueue<false> &audio_queue) :
|
AudioGenerator::AudioGenerator(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
||||||
audio_queue_(audio_queue) {}
|
audio_queue_(audio_queue) {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace MOS6560 {
|
|||||||
// audio state
|
// audio state
|
||||||
class AudioGenerator: public ::Outputs::Speaker::SampleSource {
|
class AudioGenerator: public ::Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
AudioGenerator(Concurrency::TaskQueue<false> &audio_queue);
|
AudioGenerator(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
void set_volume(uint8_t volume);
|
void set_volume(uint8_t volume);
|
||||||
void set_control(int channel, uint8_t value);
|
void set_control(int channel, uint8_t value);
|
||||||
@ -33,7 +33,7 @@ class AudioGenerator: public ::Outputs::Speaker::SampleSource {
|
|||||||
static constexpr bool get_is_stereo() { return false; }
|
static constexpr bool get_is_stereo() { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
|
|
||||||
unsigned int counters_[4] = {2, 1, 0, 0}; // create a slight phase offset for the three channels
|
unsigned int counters_[4] = {2, 1, 0, 0}; // create a slight phase offset for the three channels
|
||||||
unsigned int shift_registers_[4] = {0, 0, 0, 0};
|
unsigned int shift_registers_[4] = {0, 0, 0, 0};
|
||||||
@ -433,7 +433,7 @@ template <class BusHandler> class MOS6560 {
|
|||||||
BusHandler &bus_handler_;
|
BusHandler &bus_handler_;
|
||||||
Outputs::CRT::CRT crt_;
|
Outputs::CRT::CRT crt_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
AudioGenerator audio_generator_;
|
AudioGenerator audio_generator_;
|
||||||
Outputs::Speaker::PullLowpass<AudioGenerator> speaker_;
|
Outputs::Speaker::PullLowpass<AudioGenerator> speaker_;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
using namespace GI::AY38910;
|
using namespace GI::AY38910;
|
||||||
|
|
||||||
template <bool is_stereo>
|
template <bool is_stereo>
|
||||||
AY38910<is_stereo>::AY38910(Personality personality, Concurrency::TaskQueue<false> &task_queue) : task_queue_(task_queue) {
|
AY38910<is_stereo>::AY38910(Personality personality, Concurrency::AsyncTaskQueue<false> &task_queue) : task_queue_(task_queue) {
|
||||||
// Don't use the low bit of the envelope position if this is an AY.
|
// Don't use the low bit of the envelope position if this is an AY.
|
||||||
envelope_position_mask_ |= personality == Personality::AY38910;
|
envelope_position_mask_ |= personality == Personality::AY38910;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ enum class Personality {
|
|||||||
template <bool is_stereo> class AY38910: public ::Outputs::Speaker::SampleSource {
|
template <bool is_stereo> class AY38910: public ::Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
/// Creates a new AY38910.
|
/// Creates a new AY38910.
|
||||||
AY38910(Personality, Concurrency::TaskQueue<false> &);
|
AY38910(Personality, Concurrency::AsyncTaskQueue<false> &);
|
||||||
|
|
||||||
/// Sets the value the AY would read from its data lines if it were not outputting.
|
/// Sets the value the AY would read from its data lines if it were not outputting.
|
||||||
void set_data_input(uint8_t r);
|
void set_data_input(uint8_t r);
|
||||||
@ -114,7 +114,7 @@ template <bool is_stereo> class AY38910: public ::Outputs::Speaker::SampleSource
|
|||||||
static constexpr bool get_is_stereo() { return is_stereo; }
|
static constexpr bool get_is_stereo() { return is_stereo; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &task_queue_;
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
||||||
|
|
||||||
int selected_register_ = 0;
|
int selected_register_ = 0;
|
||||||
uint8_t registers_[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t registers_[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
using namespace Audio;
|
using namespace Audio;
|
||||||
|
|
||||||
Audio::Toggle::Toggle(Concurrency::TaskQueue<false> &audio_queue) :
|
Audio::Toggle::Toggle(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
||||||
audio_queue_(audio_queue) {}
|
audio_queue_(audio_queue) {}
|
||||||
|
|
||||||
void Toggle::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
void Toggle::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||||
|
@ -19,7 +19,7 @@ namespace Audio {
|
|||||||
*/
|
*/
|
||||||
class Toggle: public Outputs::Speaker::SampleSource {
|
class Toggle: public Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
Toggle(Concurrency::TaskQueue<false> &audio_queue);
|
Toggle(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||||
void set_sample_volume_range(std::int16_t range);
|
void set_sample_volume_range(std::int16_t range);
|
||||||
@ -31,7 +31,7 @@ class Toggle: public Outputs::Speaker::SampleSource {
|
|||||||
private:
|
private:
|
||||||
// Accessed on the calling thread.
|
// Accessed on the calling thread.
|
||||||
bool is_enabled_ = false;
|
bool is_enabled_ = false;
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
|
|
||||||
// Accessed on the audio thread.
|
// Accessed on the audio thread.
|
||||||
int16_t level_ = 0, volume_ = 0;
|
int16_t level_ = 0, volume_ = 0;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
using namespace Konami;
|
using namespace Konami;
|
||||||
|
|
||||||
SCC::SCC(Concurrency::TaskQueue<false> &task_queue) :
|
SCC::SCC(Concurrency::AsyncTaskQueue<false> &task_queue) :
|
||||||
task_queue_(task_queue) {}
|
task_queue_(task_queue) {}
|
||||||
|
|
||||||
bool SCC::is_zero_level() const {
|
bool SCC::is_zero_level() const {
|
||||||
|
@ -24,7 +24,7 @@ namespace Konami {
|
|||||||
class SCC: public ::Outputs::Speaker::SampleSource {
|
class SCC: public ::Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
/// Creates a new SCC.
|
/// Creates a new SCC.
|
||||||
SCC(Concurrency::TaskQueue<false> &task_queue);
|
SCC(Concurrency::AsyncTaskQueue<false> &task_queue);
|
||||||
|
|
||||||
/// As per ::SampleSource; provides a broadphase test for silence.
|
/// As per ::SampleSource; provides a broadphase test for silence.
|
||||||
bool is_zero_level() const;
|
bool is_zero_level() const;
|
||||||
@ -41,7 +41,7 @@ class SCC: public ::Outputs::Speaker::SampleSource {
|
|||||||
uint8_t read(uint16_t address);
|
uint8_t read(uint16_t address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &task_queue_;
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
||||||
|
|
||||||
// State from here on down is accessed ony from the audio thread.
|
// State from here on down is accessed ony from the audio thread.
|
||||||
int master_divider_ = 0;
|
int master_divider_ = 0;
|
||||||
|
@ -26,9 +26,9 @@ template <typename Child> class OPLBase: public ::Outputs::Speaker::SampleSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OPLBase(Concurrency::TaskQueue<false> &task_queue) : task_queue_(task_queue) {}
|
OPLBase(Concurrency::AsyncTaskQueue<false> &task_queue) : task_queue_(task_queue) {}
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> &task_queue_;
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t selected_register_ = 0;
|
uint8_t selected_register_ = 0;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
using namespace Yamaha::OPL;
|
using namespace Yamaha::OPL;
|
||||||
|
|
||||||
OPLL::OPLL(Concurrency::TaskQueue<false> &task_queue, int audio_divider, bool is_vrc7):
|
OPLL::OPLL(Concurrency::AsyncTaskQueue<false> &task_queue, int audio_divider, bool is_vrc7):
|
||||||
OPLBase(task_queue), audio_divider_(audio_divider), is_vrc7_(is_vrc7) {
|
OPLBase(task_queue), audio_divider_(audio_divider), is_vrc7_(is_vrc7) {
|
||||||
// Due to the way that sound mixing works on the OPLL, the audio divider may not
|
// Due to the way that sound mixing works on the OPLL, the audio divider may not
|
||||||
// be larger than 4.
|
// be larger than 4.
|
||||||
|
@ -24,7 +24,7 @@ namespace OPL {
|
|||||||
class OPLL: public OPLBase<OPLL> {
|
class OPLL: public OPLBase<OPLL> {
|
||||||
public:
|
public:
|
||||||
/// Creates a new OPLL or VRC7.
|
/// Creates a new OPLL or VRC7.
|
||||||
OPLL(Concurrency::TaskQueue<false> &task_queue, int audio_divider = 1, bool is_vrc7 = false);
|
OPLL(Concurrency::AsyncTaskQueue<false> &task_queue, int audio_divider = 1, bool is_vrc7 = false);
|
||||||
|
|
||||||
/// As per ::SampleSource; provides audio output.
|
/// As per ::SampleSource; provides audio output.
|
||||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
using namespace TI;
|
using namespace TI;
|
||||||
|
|
||||||
SN76489::SN76489(Personality personality, Concurrency::TaskQueue<false> &task_queue, int additional_divider) : task_queue_(task_queue) {
|
SN76489::SN76489(Personality personality, Concurrency::AsyncTaskQueue<false> &task_queue, int additional_divider) : task_queue_(task_queue) {
|
||||||
set_sample_volume_range(0);
|
set_sample_volume_range(0);
|
||||||
|
|
||||||
switch(personality) {
|
switch(personality) {
|
||||||
|
@ -23,7 +23,7 @@ class SN76489: public Outputs::Speaker::SampleSource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new SN76489.
|
/// Creates a new SN76489.
|
||||||
SN76489(Personality personality, Concurrency::TaskQueue<false> &task_queue, int additional_divider = 1);
|
SN76489(Personality personality, Concurrency::AsyncTaskQueue<false> &task_queue, int additional_divider = 1);
|
||||||
|
|
||||||
/// Writes a new value to the SN76489.
|
/// Writes a new value to the SN76489.
|
||||||
void write(uint8_t value);
|
void write(uint8_t value);
|
||||||
@ -41,7 +41,7 @@ class SN76489: public Outputs::Speaker::SampleSource {
|
|||||||
void evaluate_output_volume();
|
void evaluate_output_volume();
|
||||||
int volumes_[16];
|
int volumes_[16];
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> &task_queue_;
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
||||||
|
|
||||||
struct ToneChannel {
|
struct ToneChannel {
|
||||||
// Programmatically-set state; updated by the processor.
|
// Programmatically-set state; updated by the processor.
|
||||||
|
@ -17,11 +17,6 @@
|
|||||||
|
|
||||||
#include "../ClockReceiver/TimeTypes.hpp"
|
#include "../ClockReceiver/TimeTypes.hpp"
|
||||||
|
|
||||||
#if defined(__APPLE__) && !defined(IGNORE_APPLE)
|
|
||||||
#include <dispatch/dispatch.h>
|
|
||||||
#define USE_GCD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Concurrency {
|
namespace Concurrency {
|
||||||
|
|
||||||
/// An implementation detail; provides the time-centric part of a TaskQueue with a real Performer.
|
/// An implementation detail; provides the time-centric part of a TaskQueue with a real Performer.
|
||||||
@ -52,22 +47,27 @@ template <> struct TaskQueueStorage<void> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A task queue allows a caller to enqueue void(void) functions. Those functions are guaranteed
|
A task queue allows a caller to enqueue @c void(void) functions. Those functions are guaranteed
|
||||||
to be performed serially and asynchronously from the caller.
|
to be performed serially and asynchronously from the caller.
|
||||||
|
|
||||||
If @c perform_automatically is true, functions will be performed as soon as is possible,
|
If @c perform_automatically is true, functions will be performed as soon as is possible,
|
||||||
at the cost of thread synchronisation.
|
at the cost of thread synchronisation.
|
||||||
|
|
||||||
If @c perform_automatically is false, functions will be queued up and not dispatched
|
If @c perform_automatically is false, functions will be queued up but not dispatched
|
||||||
until a call to perform().
|
until a call to perform().
|
||||||
|
|
||||||
If a @c Performer type is supplied then a public member, @c performer will be constructed
|
If a @c Performer type is supplied then a public member, @c performer will be constructed
|
||||||
with the arguments supplied to TaskQueue's constructor, and that class will receive calls of the
|
with the arguments supplied to TaskQueue's constructor. That instance will receive calls of the
|
||||||
form @c .perform(nanos) to update it to every batch of new actions.
|
form @c .perform(nanos) before every batch of new actions, indicating how much time has
|
||||||
|
passed since the previous @c perform.
|
||||||
|
|
||||||
|
@note Even if @c perform_automatically is true, actions may be batched, when a long-running
|
||||||
|
action occupies the asynchronous thread for long enough. So it is not true that @c perform will be
|
||||||
|
called once per action.
|
||||||
*/
|
*/
|
||||||
template <bool perform_automatically, typename Performer = void> class TaskQueue: public TaskQueueStorage<Performer> {
|
template <bool perform_automatically, typename Performer = void> class AsyncTaskQueue: public TaskQueueStorage<Performer> {
|
||||||
public:
|
public:
|
||||||
template <typename... Args> TaskQueue(Args&&... args) :
|
template <typename... Args> AsyncTaskQueue(Args&&... args) :
|
||||||
TaskQueueStorage<Performer>(std::forward<Args>(args)...),
|
TaskQueueStorage<Performer>(std::forward<Args>(args)...),
|
||||||
thread_{
|
thread_{
|
||||||
[this] {
|
[this] {
|
||||||
@ -157,7 +157,7 @@ template <bool perform_automatically, typename Performer = void> class TaskQueue
|
|||||||
flush_condition.wait(lock, [&has_run] { return has_run; });
|
flush_condition.wait(lock, [&has_run] { return has_run; });
|
||||||
}
|
}
|
||||||
|
|
||||||
~TaskQueue() {
|
~AsyncTaskQueue() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ class Audio: public DMADevice<4> {
|
|||||||
|
|
||||||
// Transient output state, and its destination.
|
// Transient output state, and its destination.
|
||||||
Outputs::Speaker::PushLowpass<true> speaker_;
|
Outputs::Speaker::PushLowpass<true> speaker_;
|
||||||
Concurrency::TaskQueue<true> queue_;
|
Concurrency::AsyncTaskQueue<true> queue_;
|
||||||
|
|
||||||
using AudioBuffer = std::array<int16_t, 4096>;
|
using AudioBuffer = std::array<int16_t, 4096>;
|
||||||
static constexpr int BufferCount = 3;
|
static constexpr int BufferCount = 3;
|
||||||
|
@ -156,7 +156,7 @@ class AYDeferrer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
GI::AY38910::AY38910<true> ay_;
|
GI::AY38910::AY38910<true> ay_;
|
||||||
Outputs::Speaker::PullLowpass<GI::AY38910::AY38910<true>> speaker_;
|
Outputs::Speaker::PullLowpass<GI::AY38910::AY38910<true>> speaker_;
|
||||||
HalfCycles cycles_since_update_;
|
HalfCycles cycles_since_update_;
|
||||||
|
@ -95,7 +95,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
|||||||
uint8_t ram_[65536], aux_ram_[65536];
|
uint8_t ram_[65536], aux_ram_[65536];
|
||||||
std::vector<uint8_t> rom_;
|
std::vector<uint8_t> rom_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
Audio::Toggle audio_toggle_;
|
Audio::Toggle audio_toggle_;
|
||||||
Outputs::Speaker::PullLowpass<Audio::Toggle> speaker_;
|
Outputs::Speaker::PullLowpass<Audio::Toggle> speaker_;
|
||||||
Cycles cycles_since_audio_update_;
|
Cycles cycles_since_audio_update_;
|
||||||
|
@ -1150,7 +1150,7 @@ class ConcreteMachine:
|
|||||||
Apple::Disk::DiskIIDrive drives525_[2];
|
Apple::Disk::DiskIIDrive drives525_[2];
|
||||||
|
|
||||||
// The audio parts.
|
// The audio parts.
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
Apple::IIgs::Sound::GLU sound_glu_;
|
Apple::IIgs::Sound::GLU sound_glu_;
|
||||||
Audio::Toggle audio_toggle_;
|
Audio::Toggle audio_toggle_;
|
||||||
using AudioSource = Outputs::Speaker::CompoundSource<Apple::IIgs::Sound::GLU, Audio::Toggle>;
|
using AudioSource = Outputs::Speaker::CompoundSource<Apple::IIgs::Sound::GLU, Audio::Toggle>;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
using namespace Apple::IIgs::Sound;
|
using namespace Apple::IIgs::Sound;
|
||||||
|
|
||||||
GLU::GLU(Concurrency::TaskQueue<false> &audio_queue) : audio_queue_(audio_queue) {
|
GLU::GLU(Concurrency::AsyncTaskQueue<false> &audio_queue) : audio_queue_(audio_queue) {
|
||||||
// Reset all pending stores.
|
// Reset all pending stores.
|
||||||
MemoryWrite disabled_write;
|
MemoryWrite disabled_write;
|
||||||
disabled_write.enabled = false;
|
disabled_write.enabled = false;
|
||||||
|
@ -21,7 +21,7 @@ namespace Sound {
|
|||||||
|
|
||||||
class GLU: public Outputs::Speaker::SampleSource {
|
class GLU: public Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
GLU(Concurrency::TaskQueue<false> &audio_queue);
|
GLU(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
void set_control(uint8_t);
|
void set_control(uint8_t);
|
||||||
uint8_t get_control();
|
uint8_t get_control();
|
||||||
@ -42,7 +42,7 @@ class GLU: public Outputs::Speaker::SampleSource {
|
|||||||
void skip_samples(const std::size_t number_of_samples);
|
void skip_samples(const std::size_t number_of_samples);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
|
|
||||||
uint16_t address_ = 0;
|
uint16_t address_ = 0;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ const std::size_t sample_length = 352 / 2;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::Audio(Concurrency::TaskQueue<false> &task_queue) : task_queue_(task_queue) {}
|
Audio::Audio(Concurrency::AsyncTaskQueue<false> &task_queue) : task_queue_(task_queue) {}
|
||||||
|
|
||||||
// MARK: - Inputs
|
// MARK: - Inputs
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace Macintosh {
|
|||||||
*/
|
*/
|
||||||
class Audio: public ::Outputs::Speaker::SampleSource {
|
class Audio: public ::Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
Audio(Concurrency::TaskQueue<false> &task_queue);
|
Audio(Concurrency::AsyncTaskQueue<false> &task_queue);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Macintosh audio is (partly) sourced by the same scanning
|
Macintosh audio is (partly) sourced by the same scanning
|
||||||
@ -58,7 +58,7 @@ class Audio: public ::Outputs::Speaker::SampleSource {
|
|||||||
constexpr static bool get_is_stereo() { return false; }
|
constexpr static bool get_is_stereo() { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &task_queue_;
|
Concurrency::AsyncTaskQueue<false> &task_queue_;
|
||||||
|
|
||||||
// A queue of fetched samples; read from by one thread,
|
// A queue of fetched samples; read from by one thread,
|
||||||
// written to by another.
|
// written to by another.
|
||||||
|
@ -16,7 +16,7 @@ namespace Apple {
|
|||||||
namespace Macintosh {
|
namespace Macintosh {
|
||||||
|
|
||||||
struct DeferredAudio {
|
struct DeferredAudio {
|
||||||
Concurrency::TaskQueue<false> queue;
|
Concurrency::AsyncTaskQueue<false> queue;
|
||||||
Audio audio;
|
Audio audio;
|
||||||
Outputs::Speaker::PullLowpass<Audio> speaker;
|
Outputs::Speaker::PullLowpass<Audio> speaker;
|
||||||
HalfCycles time_since_update;
|
HalfCycles time_since_update;
|
||||||
|
@ -39,7 +39,7 @@ class Bus {
|
|||||||
PIA mos6532_;
|
PIA mos6532_;
|
||||||
TIA tia_;
|
TIA tia_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
TIASound tia_sound_;
|
TIASound tia_sound_;
|
||||||
Outputs::Speaker::PullLowpass<TIASound> speaker_;
|
Outputs::Speaker::PullLowpass<TIASound> speaker_;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
using namespace Atari2600;
|
using namespace Atari2600;
|
||||||
|
|
||||||
Atari2600::TIASound::TIASound(Concurrency::TaskQueue<false> &audio_queue) :
|
Atari2600::TIASound::TIASound(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
||||||
audio_queue_(audio_queue),
|
audio_queue_(audio_queue),
|
||||||
poly4_counter_{0x00f, 0x00f},
|
poly4_counter_{0x00f, 0x00f},
|
||||||
poly5_counter_{0x01f, 0x01f},
|
poly5_counter_{0x01f, 0x01f},
|
||||||
|
@ -20,7 +20,7 @@ constexpr int CPUTicksPerAudioTick = 2;
|
|||||||
|
|
||||||
class TIASound: public Outputs::Speaker::SampleSource {
|
class TIASound: public Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
TIASound(Concurrency::TaskQueue<false> &audio_queue);
|
TIASound(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
void set_volume(int channel, uint8_t volume);
|
void set_volume(int channel, uint8_t volume);
|
||||||
void set_divider(int channel, uint8_t divider);
|
void set_divider(int channel, uint8_t divider);
|
||||||
@ -32,7 +32,7 @@ class TIASound: public Outputs::Speaker::SampleSource {
|
|||||||
static constexpr bool get_is_stereo() { return false; }
|
static constexpr bool get_is_stereo() { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
|
|
||||||
uint8_t volume_[2];
|
uint8_t volume_[2];
|
||||||
uint8_t divider_[2];
|
uint8_t divider_[2];
|
||||||
|
@ -485,7 +485,7 @@ class ConcreteMachine:
|
|||||||
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles, 16> keyboard_acia_;
|
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles, 16> keyboard_acia_;
|
||||||
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles, 16> midi_acia_;
|
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles, 16> midi_acia_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
GI::AY38910::AY38910<false> ay_;
|
GI::AY38910::AY38910<false> ay_;
|
||||||
Outputs::Speaker::PullLowpass<GI::AY38910::AY38910<false>> speaker_;
|
Outputs::Speaker::PullLowpass<GI::AY38910::AY38910<false>> speaker_;
|
||||||
HalfCycles cycles_since_audio_update_;
|
HalfCycles cycles_since_audio_update_;
|
||||||
|
@ -381,7 +381,7 @@ class ConcreteMachine:
|
|||||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||||
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
TI::SN76489 sn76489_;
|
TI::SN76489 sn76489_;
|
||||||
GI::AY38910::AY38910<false> ay_;
|
GI::AY38910::AY38910<false> ay_;
|
||||||
Outputs::Speaker::CompoundSource<TI::SN76489, GI::AY38910::AY38910<false>> mixer_;
|
Outputs::Speaker::CompoundSource<TI::SN76489, GI::AY38910::AY38910<false>> mixer_;
|
||||||
|
@ -770,7 +770,7 @@ template <bool has_scsi_bus> class ConcreteMachine:
|
|||||||
// Outputs
|
// Outputs
|
||||||
JustInTimeActor<VideoOutput, Cycles> video_;
|
JustInTimeActor<VideoOutput, Cycles> video_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
SoundGenerator sound_generator_;
|
SoundGenerator sound_generator_;
|
||||||
Outputs::Speaker::PullLowpass<SoundGenerator> speaker_;
|
Outputs::Speaker::PullLowpass<SoundGenerator> speaker_;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
using namespace Electron;
|
using namespace Electron;
|
||||||
|
|
||||||
SoundGenerator::SoundGenerator(Concurrency::TaskQueue<false> &audio_queue) :
|
SoundGenerator::SoundGenerator(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
||||||
audio_queue_(audio_queue) {}
|
audio_queue_(audio_queue) {}
|
||||||
|
|
||||||
void SoundGenerator::set_sample_volume_range(std::int16_t range) {
|
void SoundGenerator::set_sample_volume_range(std::int16_t range) {
|
||||||
|
@ -16,7 +16,7 @@ namespace Electron {
|
|||||||
|
|
||||||
class SoundGenerator: public ::Outputs::Speaker::SampleSource {
|
class SoundGenerator: public ::Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
SoundGenerator(Concurrency::TaskQueue<false> &audio_queue);
|
SoundGenerator(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
void set_divider(uint8_t divider);
|
void set_divider(uint8_t divider);
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class SoundGenerator: public ::Outputs::Speaker::SampleSource {
|
|||||||
static constexpr bool get_is_stereo() { return false; }
|
static constexpr bool get_is_stereo() { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
unsigned int counter_ = 0;
|
unsigned int counter_ = 0;
|
||||||
unsigned int divider_ = 0;
|
unsigned int divider_ = 0;
|
||||||
bool is_enabled_ = false;
|
bool is_enabled_ = false;
|
||||||
|
@ -12,7 +12,7 @@ using namespace Enterprise::Dave;
|
|||||||
|
|
||||||
// MARK: - Audio generator
|
// MARK: - Audio generator
|
||||||
|
|
||||||
Audio::Audio(Concurrency::TaskQueue<false> &audio_queue) :
|
Audio::Audio(Concurrency::AsyncTaskQueue<false> &audio_queue) :
|
||||||
audio_queue_(audio_queue) {}
|
audio_queue_(audio_queue) {}
|
||||||
|
|
||||||
void Audio::write(uint16_t address, uint8_t value) {
|
void Audio::write(uint16_t address, uint8_t value) {
|
||||||
|
@ -30,7 +30,7 @@ enum class Interrupt: uint8_t {
|
|||||||
*/
|
*/
|
||||||
class Audio: public Outputs::Speaker::SampleSource {
|
class Audio: public Outputs::Speaker::SampleSource {
|
||||||
public:
|
public:
|
||||||
Audio(Concurrency::TaskQueue<false> &audio_queue);
|
Audio(Concurrency::AsyncTaskQueue<false> &audio_queue);
|
||||||
|
|
||||||
/// Modifies an register in the audio range; only the low 4 bits are
|
/// Modifies an register in the audio range; only the low 4 bits are
|
||||||
/// used for register decoding so it's assumed that the caller has
|
/// used for register decoding so it's assumed that the caller has
|
||||||
@ -43,7 +43,7 @@ class Audio: public Outputs::Speaker::SampleSource {
|
|||||||
void get_samples(std::size_t number_of_samples, int16_t *target);
|
void get_samples(std::size_t number_of_samples, int16_t *target);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
|
|
||||||
// Global divider (i.e. 8MHz/12Mhz switch).
|
// Global divider (i.e. 8MHz/12Mhz switch).
|
||||||
uint8_t global_divider_;
|
uint8_t global_divider_;
|
||||||
|
@ -705,7 +705,7 @@ template <bool has_disk_controller, bool is_6mhz> class ConcreteMachine:
|
|||||||
bool previous_nick_interrupt_line_ = false;
|
bool previous_nick_interrupt_line_ = false;
|
||||||
// Cf. timing guesses above.
|
// Cf. timing guesses above.
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
Dave::Audio dave_audio_;
|
Dave::Audio dave_audio_;
|
||||||
Outputs::Speaker::PullLowpass<Dave::Audio> speaker_;
|
Outputs::Speaker::PullLowpass<Dave::Audio> speaker_;
|
||||||
HalfCycles time_since_audio_update_;
|
HalfCycles time_since_audio_update_;
|
||||||
|
@ -747,7 +747,7 @@ class ConcreteMachine:
|
|||||||
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
||||||
Intel::i8255::i8255<i8255PortHandler> i8255_;
|
Intel::i8255::i8255<i8255PortHandler> i8255_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
GI::AY38910::AY38910<false> ay_;
|
GI::AY38910::AY38910<false> ay_;
|
||||||
Audio::Toggle audio_toggle_;
|
Audio::Toggle audio_toggle_;
|
||||||
Konami::SCC scc_;
|
Konami::SCC scc_;
|
||||||
|
@ -487,7 +487,7 @@ class ConcreteMachine:
|
|||||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||||
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
TI::SN76489 sn76489_;
|
TI::SN76489 sn76489_;
|
||||||
Yamaha::OPL::OPLL opll_;
|
Yamaha::OPL::OPLL opll_;
|
||||||
Outputs::Speaker::CompoundSource<decltype(sn76489_), decltype(opll_)> mixer_;
|
Outputs::Speaker::CompoundSource<decltype(sn76489_), decltype(opll_)> mixer_;
|
||||||
|
@ -178,7 +178,7 @@ class TapePlayer: public Storage::Tape::BinaryTapePlayer {
|
|||||||
*/
|
*/
|
||||||
class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
|
class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
|
||||||
public:
|
public:
|
||||||
VIAPortHandler(Concurrency::TaskQueue<false> &audio_queue, AY &ay8910, Speaker &speaker, TapePlayer &tape_player, Keyboard &keyboard) :
|
VIAPortHandler(Concurrency::AsyncTaskQueue<false> &audio_queue, AY &ay8910, Speaker &speaker, TapePlayer &tape_player, Keyboard &keyboard) :
|
||||||
audio_queue_(audio_queue), ay8910_(ay8910), speaker_(speaker), tape_player_(tape_player), keyboard_(keyboard)
|
audio_queue_(audio_queue), ay8910_(ay8910), speaker_(speaker), tape_player_(tape_player), keyboard_(keyboard)
|
||||||
{
|
{
|
||||||
// Attach a couple of joysticks.
|
// Attach a couple of joysticks.
|
||||||
@ -254,7 +254,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
|
|||||||
uint8_t porta_output_ = 0xff;
|
uint8_t porta_output_ = 0xff;
|
||||||
HalfCycles cycles_since_ay_update_;
|
HalfCycles cycles_since_ay_update_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> &audio_queue_;
|
Concurrency::AsyncTaskQueue<false> &audio_queue_;
|
||||||
AY &ay8910_;
|
AY &ay8910_;
|
||||||
Speaker &speaker_;
|
Speaker &speaker_;
|
||||||
TapePlayer &tape_player_;
|
TapePlayer &tape_player_;
|
||||||
@ -711,7 +711,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS
|
|||||||
// Outputs
|
// Outputs
|
||||||
JustInTimeActor<VideoOutput, Cycles> video_;
|
JustInTimeActor<VideoOutput, Cycles> video_;
|
||||||
|
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
GI::AY38910::AY38910<false> ay8910_;
|
GI::AY38910::AY38910<false> ay8910_;
|
||||||
Speaker speaker_;
|
Speaker speaker_;
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Audio
|
// MARK: - Audio
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
using AY = GI::AY38910::AY38910<false>;
|
using AY = GI::AY38910::AY38910<false>;
|
||||||
AY ay_;
|
AY ay_;
|
||||||
Outputs::Speaker::PullLowpass<AY> speaker_;
|
Outputs::Speaker::PullLowpass<AY> speaker_;
|
||||||
|
@ -849,7 +849,7 @@ template<Model model> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Audio.
|
// MARK: - Audio.
|
||||||
Concurrency::TaskQueue<false> audio_queue_;
|
Concurrency::AsyncTaskQueue<false> audio_queue_;
|
||||||
GI::AY38910::AY38910<false> ay_;
|
GI::AY38910::AY38910<false> ay_;
|
||||||
Audio::Toggle audio_toggle_;
|
Audio::Toggle audio_toggle_;
|
||||||
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910<false>, Audio::Toggle> mixer_;
|
Outputs::Speaker::CompoundSource<GI::AY38910::AY38910<false>, Audio::Toggle> mixer_;
|
||||||
|
@ -122,7 +122,7 @@ struct ActivityObserver: public Activity::Observer {
|
|||||||
CSJoystickManager *_joystickManager;
|
CSJoystickManager *_joystickManager;
|
||||||
NSMutableArray<CSMachineLED *> *_leds;
|
NSMutableArray<CSMachineLED *> *_leds;
|
||||||
|
|
||||||
Concurrency::TaskQueue<true, MachineUpdater> updater;
|
Concurrency::AsyncTaskQueue<true, MachineUpdater> updater;
|
||||||
Time::ScanSynchroniser _scanSynchroniser;
|
Time::ScanSynchroniser _scanSynchroniser;
|
||||||
|
|
||||||
NSTimer *_joystickTimer;
|
NSTimer *_joystickTimer;
|
||||||
|
@ -372,7 +372,7 @@ template <typename SampleSource> class PullLowpass: public LowpassBase<PullLowpa
|
|||||||
The speaker will advance by obtaining data from the sample source supplied
|
The speaker will advance by obtaining data from the sample source supplied
|
||||||
at construction, filtering it and passing it on to the speaker's delegate if there is one.
|
at construction, filtering it and passing it on to the speaker's delegate if there is one.
|
||||||
*/
|
*/
|
||||||
void run_for(Concurrency::TaskQueue<false> &queue, const Cycles cycles) {
|
void run_for(Concurrency::AsyncTaskQueue<false> &queue, const Cycles cycles) {
|
||||||
if(cycles == Cycles(0)) {
|
if(cycles == Cycles(0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class DiskImageHolderBase: public Disk {
|
|||||||
protected:
|
protected:
|
||||||
std::set<Track::Address> unwritten_tracks_;
|
std::set<Track::Address> unwritten_tracks_;
|
||||||
std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
|
std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
|
||||||
std::unique_ptr<Concurrency::TaskQueue<true>> update_queue_;
|
std::unique_ptr<Concurrency::AsyncTaskQueue<true>> update_queue_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -20,7 +20,7 @@ template <typename T> bool DiskImageHolder<T>::get_is_read_only() {
|
|||||||
|
|
||||||
template <typename T> void DiskImageHolder<T>::flush_tracks() {
|
template <typename T> void DiskImageHolder<T>::flush_tracks() {
|
||||||
if(!unwritten_tracks_.empty()) {
|
if(!unwritten_tracks_.empty()) {
|
||||||
if(!update_queue_) update_queue_ = std::make_unique<Concurrency::TaskQueue<true>>();
|
if(!update_queue_) update_queue_ = std::make_unique<Concurrency::AsyncTaskQueue<true>>();
|
||||||
|
|
||||||
using TrackMap = std::map<Track::Address, std::shared_ptr<Track>>;
|
using TrackMap = std::map<Track::Address, std::shared_ptr<Track>>;
|
||||||
std::shared_ptr<TrackMap> track_copies(new TrackMap);
|
std::shared_ptr<TrackMap> track_copies(new TrackMap);
|
||||||
|
Loading…
Reference in New Issue
Block a user