1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-16 22:28:57 +00:00
CLK/Machines/Amiga/Audio.hpp
2021-11-11 09:24:15 -05:00

82 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Audio.hpp
// Clock Signal
//
// Created by Thomas Harte on 09/11/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Audio_hpp
#define Audio_hpp
#include "DMADevice.hpp"
#include "../../ClockReceiver/ClockReceiver.hpp"
#include "../../Concurrency/AsyncTaskQueue.hpp"
namespace Amiga {
class Audio: public DMADevice<4> {
public:
Audio(
Chipset &chipset, uint16_t *ram, size_t word_size,
[[maybe_unused]] double output_rate) :
DMADevice<4>(chipset, ram, word_size) {}
/// Idiomatic call-in for DMA scheduling; indicates that this class may
/// perform a DMA access for the stated channel now.
bool advance(int channel);
/// Standard JustInTimeActor item; allows this class to track the
/// amount of time between other events.
void run_for(HalfCycles);
/// Sets the total number of words to fetch for the given channel.
void set_length(int channel, uint16_t);
/// Sets the number of DMA windows between each 8-bit output,
/// in the same time base as @c ticks_per_line.
void set_period(int channel, uint16_t);
/// Sets the output volume for the given channel; if bit 6 is set
/// then output is maximal; otherwise bits 05 select
/// a volume of [063]/64, on a logarithmic scale.
void set_volume(int channel, uint16_t);
/// Sets the next two samples of audio to output.
void set_data(int channel, uint16_t);
/// Provides a copy of the DMA enable flags, for the purpose of
/// determining which channels are enabled for DMA.
void set_channel_enables(uint16_t);
/// Sets which channels, if any, modulate period or volume of
/// their neighbours.
void set_modulation_flags(uint16_t);
private:
struct Channel {
// The data latch plus a count of unused samples
// in the latch, which will always be 0, 1 or 2.
uint16_t data = 0x0000;
int samples_remaining = 0;
// Number of words remaining in DMA data.
uint16_t length = 0;
// Number of ticks between each sample, plus the
// current counter, which counts downward.
uint16_t period = 0;
uint16_t period_counter = 0;
// Output volume, [0, 64].
uint8_t volume;
// Indicates whether DMA is enabled for this channel.
bool dma_enabled = false;
} channels_[4];
};
}
#endif /* Audio_hpp */