mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-02-10 01:30:32 +00:00
Wire audio frame counter (tbc)
Signed-off-by: Adrian.Conlon <adrian.conlon@arup.com>
This commit is contained in:
parent
cd63636895
commit
877618f973
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <Processor.h>
|
#include <Processor.h>
|
||||||
|
|
||||||
|
#include "AudioFrame.h"
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
namespace GameBoy {
|
namespace GameBoy {
|
||||||
|
|
||||||
@ -110,7 +112,8 @@ namespace EightBit {
|
|||||||
|
|
||||||
class WaveVoice : public AudioVoice {
|
class WaveVoice : public AudioVoice {
|
||||||
public:
|
public:
|
||||||
WaveVoice() {}
|
WaveVoice(int cyclesPerSecond)
|
||||||
|
: m_cyclesPerSecond(cyclesPerSecond) {}
|
||||||
|
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
AudioVoice::reset();
|
AudioVoice::reset();
|
||||||
@ -141,9 +144,8 @@ namespace EightBit {
|
|||||||
|
|
||||||
int hertz() const {
|
int hertz() const {
|
||||||
// f = 4194304 / (4 x 8 x (2048 - X)) Hz
|
// f = 4194304 / (4 x 8 x (2048 - X)) Hz
|
||||||
auto clock = 4 * 1024 * 1024;
|
|
||||||
auto division = 4 * 8 * (2048 - frequency());
|
auto division = 4 * 8 * (2048 - frequency());
|
||||||
return clock / division;
|
return m_cyclesPerSecond / division;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFrequency(int value) {
|
void setFrequency(int value) {
|
||||||
@ -158,13 +160,15 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const int m_cyclesPerSecond;
|
||||||
int m_frequencyLowOrder; // 8 bits
|
int m_frequencyLowOrder; // 8 bits
|
||||||
int m_frequencyHighOrder; // 3 bits
|
int m_frequencyHighOrder; // 3 bits
|
||||||
};
|
};
|
||||||
|
|
||||||
class RectangularVoice : public WaveVoice {
|
class RectangularVoice : public WaveVoice {
|
||||||
public:
|
public:
|
||||||
RectangularVoice() {}
|
RectangularVoice(int cyclesPerSecond)
|
||||||
|
: WaveVoice(cyclesPerSecond) {}
|
||||||
|
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
WaveVoice::reset();
|
WaveVoice::reset();
|
||||||
@ -194,7 +198,8 @@ namespace EightBit {
|
|||||||
// NR2X
|
// NR2X
|
||||||
class EnvelopedRectangularVoice : public RectangularVoice {
|
class EnvelopedRectangularVoice : public RectangularVoice {
|
||||||
public:
|
public:
|
||||||
EnvelopedRectangularVoice() {}
|
EnvelopedRectangularVoice(int cyclesPerSecond)
|
||||||
|
: RectangularVoice(cyclesPerSecond) {}
|
||||||
|
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
RectangularVoice::reset();
|
RectangularVoice::reset();
|
||||||
@ -219,7 +224,8 @@ namespace EightBit {
|
|||||||
// NR1X
|
// NR1X
|
||||||
class SweptEnvelopedRectangularVoice : public EnvelopedRectangularVoice {
|
class SweptEnvelopedRectangularVoice : public EnvelopedRectangularVoice {
|
||||||
public:
|
public:
|
||||||
SweptEnvelopedRectangularVoice() {}
|
SweptEnvelopedRectangularVoice(int cyclesPerSecond)
|
||||||
|
: EnvelopedRectangularVoice(cyclesPerSecond) {}
|
||||||
|
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
EnvelopedRectangularVoice::reset();
|
EnvelopedRectangularVoice::reset();
|
||||||
@ -244,7 +250,8 @@ namespace EightBit {
|
|||||||
// NR3X
|
// NR3X
|
||||||
class UserDefinedWaveVoice : public WaveVoice {
|
class UserDefinedWaveVoice : public WaveVoice {
|
||||||
public:
|
public:
|
||||||
UserDefinedWaveVoice() {}
|
UserDefinedWaveVoice(int cyclesPerSecond)
|
||||||
|
: WaveVoice(cyclesPerSecond) {}
|
||||||
|
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
WaveVoice::reset();
|
WaveVoice::reset();
|
||||||
@ -391,12 +398,19 @@ namespace EightBit {
|
|||||||
|
|
||||||
class Audio final {
|
class Audio final {
|
||||||
public:
|
public:
|
||||||
Audio()
|
Audio(int cyclesPerSecond)
|
||||||
: m_enabled(false) {
|
: m_frameSequencer(cyclesPerSecond),
|
||||||
m_voices[0] = std::make_shared<SweptEnvelopedRectangularVoice>();
|
m_enabled(false) {
|
||||||
m_voices[1] = std::make_shared<EnvelopedRectangularVoice>();
|
|
||||||
m_voices[2] = std::make_shared<UserDefinedWaveVoice>();
|
m_voices[0] = std::make_shared<SweptEnvelopedRectangularVoice>(cyclesPerSecond);
|
||||||
|
m_voices[1] = std::make_shared<EnvelopedRectangularVoice>(cyclesPerSecond);
|
||||||
|
m_voices[2] = std::make_shared<UserDefinedWaveVoice>(cyclesPerSecond);
|
||||||
m_voices[3] = std::make_shared<WhiteNoiseWaveVoice>();
|
m_voices[3] = std::make_shared<WhiteNoiseWaveVoice>();
|
||||||
|
|
||||||
|
m_frameSequencer.FrameStep.connect(std::bind(&Audio::Sequencer_FrameStep, this, std::placeholders::_1));
|
||||||
|
m_frameSequencer.LengthStep.connect(std::bind(&Audio::Sequencer_LengthStep, this, std::placeholders::_1));
|
||||||
|
m_frameSequencer.VolumeStep.connect(std::bind(&Audio::Sequencer_VolumeStep, this, std::placeholders::_1));
|
||||||
|
m_frameSequencer.SweepStep.connect(std::bind(&Audio::Sequencer_SweepStep, this, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AudioVoice> voice(int i) { return m_voices[i]; }
|
std::shared_ptr<AudioVoice> voice(int i) { return m_voices[i]; }
|
||||||
@ -759,7 +773,25 @@ namespace EightBit {
|
|||||||
return voice3()->packedWaveDatum(i);
|
return voice3()->packedWaveDatum(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stepFrame(int cycles) {
|
||||||
|
m_frameSequencer.step(cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer_FrameStep(const int step) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer_LengthStep(const int step) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer_VolumeStep(const int step) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer_SweepStep(const int step) {
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AudioFrame m_frameSequencer;
|
||||||
|
|
||||||
std::array<std::shared_ptr<AudioVoice>, 4> m_voices;
|
std::array<std::shared_ptr<AudioVoice>, 4> m_voices;
|
||||||
std::array<OutputChannel, 2> m_channels;
|
std::array<OutputChannel, 2> m_channels;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
|
47
LR35902/inc/AudioFrame.h
Normal file
47
LR35902/inc/AudioFrame.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Signal.h>
|
||||||
|
|
||||||
|
namespace EightBit {
|
||||||
|
namespace GameBoy {
|
||||||
|
class AudioFrame final {
|
||||||
|
private:
|
||||||
|
enum { StepCycle = 7, Frequency = 512 };
|
||||||
|
|
||||||
|
int m_cyclesPerTick;
|
||||||
|
int m_currentStep;
|
||||||
|
int m_currentCycles;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AudioFrame(int cyclesPerSecond)
|
||||||
|
: m_cyclesPerTick(cyclesPerSecond / Frequency),
|
||||||
|
m_currentStep(0),
|
||||||
|
m_currentCycles(m_cyclesPerTick) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Signal<int> FrameStep;
|
||||||
|
Signal<int> LengthStep;
|
||||||
|
Signal<int> VolumeStep;
|
||||||
|
Signal<int> SweepStep;
|
||||||
|
|
||||||
|
void step() {
|
||||||
|
m_currentStep = (m_currentStep + 1) % StepCycle;
|
||||||
|
FrameStep.fire(m_currentStep);
|
||||||
|
if ((m_currentStep % 2) == 0)
|
||||||
|
LengthStep.fire(m_currentStep);
|
||||||
|
if (m_currentStep == 7)
|
||||||
|
VolumeStep.fire(m_currentStep);
|
||||||
|
if ((m_currentStep == 2) || (m_currentStep == 6))
|
||||||
|
SweepStep.fire(m_currentStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step(int cycles) {
|
||||||
|
m_currentCycles -= cycles;
|
||||||
|
if (m_currentCycles < 0) {
|
||||||
|
step();
|
||||||
|
m_currentCycles += m_cyclesPerTick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,8 @@ EightBit::GameBoy::Bus::Bus()
|
|||||||
m_p13(true),
|
m_p13(true),
|
||||||
m_p12(true),
|
m_p12(true),
|
||||||
m_p11(true),
|
m_p11(true),
|
||||||
m_p10(true) {
|
m_p10(true),
|
||||||
|
m_audio(CyclesPerSecond) {
|
||||||
ReadingByte.connect(std::bind(&GameBoy::Bus::Bus_ReadingByte, this, std::placeholders::_1));
|
ReadingByte.connect(std::bind(&GameBoy::Bus::Bus_ReadingByte, this, std::placeholders::_1));
|
||||||
WrittenByte.connect(std::bind(&GameBoy::Bus::Bus_WrittenByte, this, std::placeholders::_1));
|
WrittenByte.connect(std::bind(&GameBoy::Bus::Bus_WrittenByte, this, std::placeholders::_1));
|
||||||
m_divCounter.word = 0xabcc;
|
m_divCounter.word = 0xabcc;
|
||||||
|
@ -141,6 +141,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\inc\AbstractColourPalette.h" />
|
<ClInclude Include="..\inc\AbstractColourPalette.h" />
|
||||||
<ClInclude Include="..\inc\Audio.h" />
|
<ClInclude Include="..\inc\Audio.h" />
|
||||||
|
<ClInclude Include="..\inc\AudioFrame.h" />
|
||||||
<ClInclude Include="..\inc\GameBoyBus.h" />
|
<ClInclude Include="..\inc\GameBoyBus.h" />
|
||||||
<ClInclude Include="..\inc\CharacterDefinition.h" />
|
<ClInclude Include="..\inc\CharacterDefinition.h" />
|
||||||
<ClInclude Include="..\inc\Disassembler.h" />
|
<ClInclude Include="..\inc\Disassembler.h" />
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
<ClInclude Include="..\inc\Audio.h">
|
<ClInclude Include="..\inc\Audio.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\AudioFrame.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user