mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-10 12:29:01 +00:00
Factored out the Electron's speaker and adjusted instance variable naming.
This commit is contained in:
parent
d1d93829cf
commit
4fac538a57
@ -31,8 +31,6 @@ namespace {
|
|||||||
|
|
||||||
static const unsigned int real_time_clock_interrupt_1 = 16704;
|
static const unsigned int real_time_clock_interrupt_1 = 16704;
|
||||||
static const unsigned int real_time_clock_interrupt_2 = 56704;
|
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)
|
#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;
|
// 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
|
// 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.
|
// 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()
|
void Machine::close_output()
|
||||||
@ -583,8 +581,8 @@ inline void Machine::update_audio()
|
|||||||
{
|
{
|
||||||
unsigned int difference = _frameCycles - _audioOutputPosition;
|
unsigned int difference = _frameCycles - _audioOutputPosition;
|
||||||
_audioOutputPosition = _frameCycles;
|
_audioOutputPosition = _frameCycles;
|
||||||
_speaker->run_for_cycles(difference / clock_rate_audio_divider);
|
_speaker->run_for_cycles(difference / Speaker::clock_rate_divider);
|
||||||
_audioOutputPositionError = difference % clock_rate_audio_divider;
|
_audioOutputPositionError = difference % Speaker::clock_rate_divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Machine::start_pixel_line()
|
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);
|
_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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "../CRTMachine.hpp"
|
#include "../CRTMachine.hpp"
|
||||||
#include "../Typer.hpp"
|
#include "../Typer.hpp"
|
||||||
#include "Plus3.hpp"
|
#include "Plus3.hpp"
|
||||||
|
#include "Speaker.hpp"
|
||||||
#include "Tape.hpp"
|
#include "Tape.hpp"
|
||||||
#include "Interrupts.hpp"
|
#include "Interrupts.hpp"
|
||||||
|
|
||||||
@ -58,21 +59,6 @@ enum Key: uint16_t {
|
|||||||
TerminateSequence = 0xffff, NotMapped = 0xfffe,
|
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.
|
@abstract Represents an Acorn Electron.
|
||||||
|
|
||||||
|
48
Machines/Electron/Speaker.cpp
Normal file
48
Machines/Electron/Speaker.cpp
Normal 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;
|
||||||
|
});
|
||||||
|
}
|
35
Machines/Electron/Speaker.hpp
Normal file
35
Machines/Electron/Speaker.hpp
Normal 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 */
|
@ -384,6 +384,7 @@
|
|||||||
4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69F921D98760000243FE1 /* AcornADF.cpp */; };
|
4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69F921D98760000243FE1 /* AcornADF.cpp */; };
|
||||||
4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; };
|
4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; };
|
||||||
4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.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 */; };
|
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */; };
|
||||||
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; };
|
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; };
|
||||||
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = "<group>"; };
|
||||||
@ -1057,11 +1060,13 @@
|
|||||||
children = (
|
children = (
|
||||||
4B2E2D9B1C3A070400138695 /* Electron.cpp */,
|
4B2E2D9B1C3A070400138695 /* Electron.cpp */,
|
||||||
4B30512E1D98ACC600B4FED8 /* Plus3.cpp */,
|
4B30512E1D98ACC600B4FED8 /* Plus3.cpp */,
|
||||||
|
4BEA52611DF339D7007E74F2 /* Speaker.cpp */,
|
||||||
4BEA525D1DF33323007E74F2 /* Tape.cpp */,
|
4BEA525D1DF33323007E74F2 /* Tape.cpp */,
|
||||||
4BC8A62B1DCE60E000DAC693 /* Typer.cpp */,
|
4BC8A62B1DCE60E000DAC693 /* Typer.cpp */,
|
||||||
4B2E2D9C1C3A070400138695 /* Electron.hpp */,
|
4B2E2D9C1C3A070400138695 /* Electron.hpp */,
|
||||||
4BEA52601DF3343A007E74F2 /* Interrupts.hpp */,
|
4BEA52601DF3343A007E74F2 /* Interrupts.hpp */,
|
||||||
4B30512F1D98ACC600B4FED8 /* Plus3.hpp */,
|
4B30512F1D98ACC600B4FED8 /* Plus3.hpp */,
|
||||||
|
4BEA52621DF339D7007E74F2 /* Speaker.hpp */,
|
||||||
4BEA525F1DF333D8007E74F2 /* Tape.hpp */,
|
4BEA525F1DF333D8007E74F2 /* Tape.hpp */,
|
||||||
);
|
);
|
||||||
name = Electron;
|
name = Electron;
|
||||||
@ -2343,6 +2348,7 @@
|
|||||||
4B2A332F1DB86869002876E3 /* OricOptionsPanel.swift in Sources */,
|
4B2A332F1DB86869002876E3 /* OricOptionsPanel.swift in Sources */,
|
||||||
4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */,
|
4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */,
|
||||||
4BF829661D8F732B001BAE39 /* Disk.cpp in Sources */,
|
4BF829661D8F732B001BAE39 /* Disk.cpp in Sources */,
|
||||||
|
4BEA52631DF339D7007E74F2 /* Speaker.cpp in Sources */,
|
||||||
4BC5E4921D7ED365008CF980 /* StaticAnalyser.cpp in Sources */,
|
4BC5E4921D7ED365008CF980 /* StaticAnalyser.cpp in Sources */,
|
||||||
4BC830D11D6E7C690000A26F /* Tape.cpp in Sources */,
|
4BC830D11D6E7C690000A26F /* Tape.cpp in Sources */,
|
||||||
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
|
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
|
||||||
|
Loading…
Reference in New Issue
Block a user