1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Factored out the Electron's speaker and adjusted instance variable naming.

This commit is contained in:
Thomas Harte 2016-12-03 12:41:02 -05:00
parent d1d93829cf
commit 4fac538a57
5 changed files with 93 additions and 62 deletions

View File

@ -31,8 +31,6 @@ namespace {
static const unsigned int real_time_clock_interrupt_1 = 16704;
static const unsigned int real_time_clock_interrupt_2 = 56704;
static const unsigned int clock_rate_audio_divider = 8;
}
#define graphics_line(v) ((((v) >> 7) - first_graphics_line + field_divider_line) % field_divider_line)
@ -76,7 +74,7 @@ void Machine::setup_output(float aspect_ratio)
// The maximum output frequency is 62500Hz and all other permitted output frequencies are integral divisions of that;
// however setting the speaker on or off can happen on any 2Mhz cycle, and probably (?) takes effect immediately. So
// run the speaker at a 2000000Hz input rate, at least for the time being.
_speaker->set_input_rate(2000000 / clock_rate_audio_divider);
_speaker->set_input_rate(2000000 / Speaker::clock_rate_divider);
}
void Machine::close_output()
@ -583,8 +581,8 @@ inline void Machine::update_audio()
{
unsigned int difference = _frameCycles - _audioOutputPosition;
_audioOutputPosition = _frameCycles;
_speaker->run_for_cycles(difference / clock_rate_audio_divider);
_audioOutputPositionError = difference % clock_rate_audio_divider;
_speaker->run_for_cycles(difference / Speaker::clock_rate_divider);
_audioOutputPositionError = difference % Speaker::clock_rate_divider;
}
inline void Machine::start_pixel_line()
@ -931,45 +929,3 @@ void Machine::set_key_state(uint16_t key, bool isPressed)
_key_states[key >> 4] &= ~(key&0xf);
}
}
/*
Speaker
*/
void Speaker::get_samples(unsigned int number_of_samples, int16_t *target)
{
if(_is_enabled)
{
while(number_of_samples--)
{
*target = (int16_t)((_counter / (_divider+1)) * 8192);
target++;
_counter = (_counter + 1) % ((_divider+1) * 2);
}
}
else
{
memset(target, 0, sizeof(int16_t) * number_of_samples);
}
}
void Speaker::skip_samples(unsigned int number_of_samples)
{
_counter = (_counter + number_of_samples) % ((_divider+1) * 2);
}
void Speaker::set_divider(uint8_t divider)
{
enqueue([=]() {
_divider = divider * 32 / clock_rate_audio_divider;
});
}
void Speaker::set_is_enabled(bool is_enabled)
{
enqueue([=]() {
_is_enabled = is_enabled;
_counter = 0;
});
}

View File

@ -16,6 +16,7 @@
#include "../CRTMachine.hpp"
#include "../Typer.hpp"
#include "Plus3.hpp"
#include "Speaker.hpp"
#include "Tape.hpp"
#include "Interrupts.hpp"
@ -58,21 +59,6 @@ enum Key: uint16_t {
TerminateSequence = 0xffff, NotMapped = 0xfffe,
};
class Speaker: public ::Outputs::Filter<Speaker> {
public:
void set_divider(uint8_t divider);
void set_is_enabled(bool is_enabled);
void get_samples(unsigned int number_of_samples, int16_t *target);
void skip_samples(unsigned int number_of_samples);
private:
unsigned int _counter;
unsigned int _divider;
bool _is_enabled;
};
/*!
@abstract Represents an Acorn Electron.

View File

@ -0,0 +1,48 @@
//
// Speaker.cpp
// Clock Signal
//
// Created by Thomas Harte on 03/12/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#include "Speaker.hpp"
using namespace Electron;
void Speaker::get_samples(unsigned int number_of_samples, int16_t *target)
{
if(is_enabled_)
{
while(number_of_samples--)
{
*target = (int16_t)((counter_ / (divider_+1)) * 8192);
target++;
counter_ = (counter_ + 1) % ((divider_+1) * 2);
}
}
else
{
memset(target, 0, sizeof(int16_t) * number_of_samples);
}
}
void Speaker::skip_samples(unsigned int number_of_samples)
{
counter_ = (counter_ + number_of_samples) % ((divider_+1) * 2);
}
void Speaker::set_divider(uint8_t divider)
{
enqueue([=]() {
divider_ = divider * 32 / clock_rate_divider;
});
}
void Speaker::set_is_enabled(bool is_enabled)
{
enqueue([=]() {
is_enabled_ = is_enabled;
counter_ = 0;
});
}

View File

@ -0,0 +1,35 @@
//
// Speaker.hpp
// Clock Signal
//
// Created by Thomas Harte on 03/12/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef Electron_Speaker_hpp
#define Electron_Speaker_hpp
#include "../../Outputs/Speaker.hpp"
namespace Electron {
class Speaker: public ::Outputs::Filter<Speaker> {
public:
void set_divider(uint8_t divider);
void set_is_enabled(bool is_enabled);
void get_samples(unsigned int number_of_samples, int16_t *target);
void skip_samples(unsigned int number_of_samples);
static const unsigned int clock_rate_divider = 8;
private:
unsigned int counter_;
unsigned int divider_;
bool is_enabled_;
};
}
#endif /* Speaker_hpp */

View File

@ -384,6 +384,7 @@
4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69F921D98760000243FE1 /* AcornADF.cpp */; };
4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; };
4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; };
4BEA52631DF339D7007E74F2 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* Speaker.cpp */; };
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */; };
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; };
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */; };
@ -896,6 +897,8 @@
4BEA525D1DF33323007E74F2 /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tape.cpp; path = Electron/Tape.cpp; sourceTree = "<group>"; };
4BEA525F1DF333D8007E74F2 /* Tape.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Tape.hpp; path = Electron/Tape.hpp; sourceTree = "<group>"; };
4BEA52601DF3343A007E74F2 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Interrupts.hpp; path = Electron/Interrupts.hpp; sourceTree = "<group>"; };
4BEA52611DF339D7007E74F2 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = Electron/Speaker.cpp; sourceTree = "<group>"; };
4BEA52621DF339D7007E74F2 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = Electron/Speaker.hpp; sourceTree = "<group>"; };
4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = "<group>"; };
4BEE0A6B1D72496600532C7B /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = "<group>"; };
@ -1057,11 +1060,13 @@
children = (
4B2E2D9B1C3A070400138695 /* Electron.cpp */,
4B30512E1D98ACC600B4FED8 /* Plus3.cpp */,
4BEA52611DF339D7007E74F2 /* Speaker.cpp */,
4BEA525D1DF33323007E74F2 /* Tape.cpp */,
4BC8A62B1DCE60E000DAC693 /* Typer.cpp */,
4B2E2D9C1C3A070400138695 /* Electron.hpp */,
4BEA52601DF3343A007E74F2 /* Interrupts.hpp */,
4B30512F1D98ACC600B4FED8 /* Plus3.hpp */,
4BEA52621DF339D7007E74F2 /* Speaker.hpp */,
4BEA525F1DF333D8007E74F2 /* Tape.hpp */,
);
name = Electron;
@ -2343,6 +2348,7 @@
4B2A332F1DB86869002876E3 /* OricOptionsPanel.swift in Sources */,
4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */,
4BF829661D8F732B001BAE39 /* Disk.cpp in Sources */,
4BEA52631DF339D7007E74F2 /* Speaker.cpp in Sources */,
4BC5E4921D7ED365008CF980 /* StaticAnalyser.cpp in Sources */,
4BC830D11D6E7C690000A26F /* Tape.cpp in Sources */,
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,