mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Separates LowpassFilter and SampleSource.
This commit is contained in:
parent
f8a2459c91
commit
2dc1d4443e
@ -12,7 +12,8 @@
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||
#include "../../Outputs/CRT/CRT.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/FilteringSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||
|
||||
namespace MOS {
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "AY38910.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace GI::AY38910;
|
||||
|
||||
AY38910::AY38910(Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(task_queue) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef AY_3_8910_hpp
|
||||
#define AY_3_8910_hpp
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/FilteringSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||
|
||||
namespace GI {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../../Storage/Tape/Tape.hpp"
|
||||
|
||||
#include "../../ClockReceiver/ForceInline.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "TIASound.hpp"
|
||||
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
namespace Atari2600 {
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef Atari2600_TIASound_hpp
|
||||
#define Atari2600_TIASound_hpp
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/FilteringSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||
|
||||
namespace Atari2600 {
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../ClockReceiver/ForceInline.hpp"
|
||||
#include "../../Configurable/StandardOptions.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/FilteringSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
#include "../../Processors/6502/6502.hpp"
|
||||
#include "../../Storage/Tape/Tape.hpp"
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef Electron_SoundGenerator_hpp
|
||||
#define Electron_SoundGenerator_hpp
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/FilteringSpeaker.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/SampleSource.hpp"
|
||||
#include "../../Concurrency/AsyncTaskQueue.hpp"
|
||||
|
||||
namespace Electron {
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "../ConfigurationTarget.hpp"
|
||||
#include "../KeyboardMachine.hpp"
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
namespace MSX {
|
||||
|
||||
struct AYPortHandler: public GI::AY38910::PortHandler {
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "../../ClockReceiver/ForceInline.hpp"
|
||||
#include "../../Configurable/StandardOptions.hpp"
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
@ -251,7 +251,6 @@
|
||||
4B8805F71DCFF6C9003085B1 /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F51DCFF6C9003085B1 /* Commodore.cpp */; };
|
||||
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F91DCFF807003085B1 /* Oric.cpp */; };
|
||||
4B8805FE1DD02552003085B1 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805FC1DD02552003085B1 /* Tape.cpp */; };
|
||||
4B8EF6081FE5AF830076CCDD /* FilteringSpeaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8EF6061FE5AF830076CCDD /* FilteringSpeaker.cpp */; };
|
||||
4B8FE21B1DA19D5F0090D3CE /* Atari2600Options.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */; };
|
||||
4B8FE21C1DA19D5F0090D3CE /* MachineDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */; };
|
||||
4B8FE21D1DA19D5F0090D3CE /* ElectronOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2171DA19D5F0090D3CE /* ElectronOptions.xib */; };
|
||||
@ -818,6 +817,7 @@
|
||||
4B643F391D77AD1900D431D6 /* CSStaticAnalyser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CSStaticAnalyser.mm; path = StaticAnalyser/CSStaticAnalyser.mm; sourceTree = "<group>"; };
|
||||
4B643F3C1D77AE5C00D431D6 /* CSMachine+Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CSMachine+Target.h"; sourceTree = "<group>"; };
|
||||
4B643F3E1D77B88000D431D6 /* DocumentController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentController.swift; sourceTree = "<group>"; };
|
||||
4B698D1A1FE768A100696C91 /* SampleSource.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = SampleSource.hpp; sourceTree = "<group>"; };
|
||||
4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tape.cpp; sourceTree = "<group>"; };
|
||||
4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tape.hpp; sourceTree = "<group>"; };
|
||||
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapeUEF.cpp; sourceTree = "<group>"; };
|
||||
@ -873,8 +873,7 @@
|
||||
4B8805FD1DD02552003085B1 /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Tape.hpp; path = ../../StaticAnalyser/Oric/Tape.hpp; sourceTree = "<group>"; };
|
||||
4B8D287E1F77207100645199 /* TrackSerialiser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TrackSerialiser.hpp; sourceTree = "<group>"; };
|
||||
4B8E4ECD1DCE483D003716C3 /* KeyboardMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KeyboardMachine.hpp; sourceTree = "<group>"; };
|
||||
4B8EF6061FE5AF830076CCDD /* FilteringSpeaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilteringSpeaker.cpp; sourceTree = "<group>"; };
|
||||
4B8EF6071FE5AF830076CCDD /* FilteringSpeaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FilteringSpeaker.hpp; sourceTree = "<group>"; };
|
||||
4B8EF6071FE5AF830076CCDD /* LowpassSpeaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = LowpassSpeaker.hpp; sourceTree = "<group>"; };
|
||||
4B8FE2141DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Atari2600Options.xib"; sourceTree = SOURCE_ROOT; };
|
||||
4B8FE2161DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MachineDocument.xib"; sourceTree = SOURCE_ROOT; };
|
||||
4B8FE2181DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/ElectronOptions.xib"; sourceTree = SOURCE_ROOT; };
|
||||
@ -2022,8 +2021,8 @@
|
||||
4B8EF6051FE5AF830076CCDD /* Implementation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8EF6061FE5AF830076CCDD /* FilteringSpeaker.cpp */,
|
||||
4B8EF6071FE5AF830076CCDD /* FilteringSpeaker.hpp */,
|
||||
4B8EF6071FE5AF830076CCDD /* LowpassSpeaker.hpp */,
|
||||
4B698D1A1FE768A100696C91 /* SampleSource.hpp */,
|
||||
);
|
||||
path = Implementation;
|
||||
sourceTree = "<group>";
|
||||
@ -3382,7 +3381,6 @@
|
||||
4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */,
|
||||
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
|
||||
4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */,
|
||||
4B8EF6081FE5AF830076CCDD /* FilteringSpeaker.cpp in Sources */,
|
||||
4B8FE2221DA19FB20090D3CE /* MachinePanel.swift in Sources */,
|
||||
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */,
|
||||
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */,
|
||||
|
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
//
|
||||
// FilteringSpeaker.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 15/12/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "FilteringSpeaker.hpp"
|
@ -15,35 +15,16 @@
|
||||
#include "../../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../../Concurrency/AsyncTaskQueue.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Outputs {
|
||||
namespace Speaker {
|
||||
|
||||
/*!
|
||||
A sample source is something that can provide a stream of audio.
|
||||
This optional base class provides the interface expected to be exposed
|
||||
by the template parameter to LowpassSpeaker.
|
||||
*/
|
||||
class SampleSource {
|
||||
public:
|
||||
/*!
|
||||
Should write the next @c number_of_samples to @c target.
|
||||
*/
|
||||
void get_samples(std::size_t number_of_samples, int16_t *target) {}
|
||||
|
||||
/*!
|
||||
Should skip the next @c number_of_samples. Subclasses of this SampleSource
|
||||
need not implement this if it would no more efficient to do so than it is
|
||||
merely to call get_samples and throw the result away, as per the default
|
||||
implementation below.
|
||||
*/
|
||||
void skip_samples(const std::size_t number_of_samples) {
|
||||
int16_t scratch_pad[number_of_samples];
|
||||
get_samples(number_of_samples, scratch_pad);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
The low-pass speaker
|
||||
The low-pass speaker expects an Outputs::Speaker::SampleSource-derived
|
||||
template class, and uses the instance supplied to its constructor as the
|
||||
source of a high-frequency stream of audio which it filters down to a
|
||||
lower-frequency output.
|
||||
*/
|
||||
template <typename T> class LowpassSpeaker: public Speaker {
|
||||
public:
|
||||
@ -156,9 +137,9 @@ template <typename T> class LowpassSpeaker: public Speaker {
|
||||
uint64_t steps = stepper_->step();
|
||||
if(steps < input_buffer_.size()) {
|
||||
int16_t *input_buffer = input_buffer_.data();
|
||||
memmove( input_buffer,
|
||||
&input_buffer[steps],
|
||||
sizeof(int16_t) * (input_buffer_.size() - steps));
|
||||
std::memmove( input_buffer,
|
||||
&input_buffer[steps],
|
||||
sizeof(int16_t) * (input_buffer_.size() - steps));
|
||||
input_buffer_depth_ -= steps;
|
||||
} else {
|
||||
if(steps > input_buffer_.size())
|
45
Outputs/Speaker/Implementation/SampleSource.hpp
Normal file
45
Outputs/Speaker/Implementation/SampleSource.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// SampleSource.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 17/12/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SampleSource_hpp
|
||||
#define SampleSource_hpp
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Outputs {
|
||||
namespace Speaker {
|
||||
|
||||
/*!
|
||||
A sample source is something that can provide a stream of audio.
|
||||
This optional base class provides the interface expected to be exposed
|
||||
by the template parameter to LowpassSpeaker.
|
||||
*/
|
||||
class SampleSource {
|
||||
public:
|
||||
/*!
|
||||
Should write the next @c number_of_samples to @c target.
|
||||
*/
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target) {}
|
||||
|
||||
/*!
|
||||
Should skip the next @c number_of_samples. Subclasses of this SampleSource
|
||||
need not implement this if it would no more efficient to do so than it is
|
||||
merely to call get_samples and throw the result away, as per the default
|
||||
implementation below.
|
||||
*/
|
||||
void skip_samples(const std::size_t number_of_samples) {
|
||||
std::int16_t scratch_pad[number_of_samples];
|
||||
get_samples(number_of_samples, scratch_pad);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SampleSource_hpp */
|
Loading…
Reference in New Issue
Block a user