openMSX
CassettePlayer.hh
Go to the documentation of this file.
1#ifndef CASSETTEPLAYER_HH
2#define CASSETTEPLAYER_HH
3
4#include "CassetteDevice.hh"
6#include "MSXMotherBoard.hh"
8#include "Schedulable.hh"
9#include "ThrottleManager.hh"
10#include "Filename.hh"
11#include "EmuTime.hh"
12#include "BooleanSetting.hh"
13#include "outer.hh"
14#include "serialize_meta.hh"
15#include <array>
16#include <cstdint>
17#include <memory>
18#include <string>
19
20namespace openmsx {
21
22class CassetteImage;
23class HardwareConfig;
24class Wav8Writer;
25
27 , public MediaInfoProvider
28{
29public:
30 static constexpr std::string_view TAPE_RECORDING_DIR = "taperecordings";
31 static constexpr std::string_view TAPE_RECORDING_EXTENSION = ".wav";
32
33public:
34 explicit CassettePlayer(const HardwareConfig& hwConf);
35 ~CassettePlayer() override;
36
37 // CassetteDevice
38 void setMotor(bool status, EmuTime::param time) override;
39 int16_t readSample(EmuTime::param time) override;
40 void setSignal(bool output, EmuTime::param time) override;
41
42 // Pluggable
43 std::string_view getName() const override;
44 std::string_view getDescription() const override;
45 void plugHelper(Connector& connector, EmuTime::param time) override;
46 void unplugHelper(EmuTime::param time) override;
47
48 // SoundDevice
49 void generateChannels(std::span<float*> buffers, unsigned num) override;
50 float getAmplificationFactorImpl() const override;
51
52 // MediaInfoProvider
53 void getMediaInfo(TclObject& result) override;
54
55 template<typename Archive>
56 void serialize(Archive& ar, unsigned version);
57
58 enum class State { PLAY, RECORD, STOP };
59
60 // methods to query the status of the player
61 const Filename& getImageName() const { return casImage; }
62 [[nodiscard]] State getState() const { return state; }
63 [[nodiscard]] bool isMotorControlEnabled() const { return motorControl; }
64
67 double getTapePos(EmuTime::param time);
68
73 double getTapeLength(EmuTime::param time);
74
76
77private:
78 [[nodiscard]] std::string getStateString() const;
79 void setState(State newState, const Filename& newImage,
80 EmuTime::param time);
81 void setImageName(const Filename& newImage);
82 void checkInvariants() const;
83
86 void playTape(const Filename& filename, EmuTime::param time);
87 void insertTape(const Filename& filename, EmuTime::param time);
88
91 void removeTape(EmuTime::param time);
92
96 void recordTape(const Filename& filename, EmuTime::param time);
97
102 void rewind(EmuTime::param time);
103 void wind(EmuTime::param time);
104
107 void setMotorControl(bool status, EmuTime::param time);
108
112 bool isRolling() const;
113
118 void updateLoadingState(EmuTime::param time);
119
122 void setTapePos(EmuTime::param time, double newPos);
123
124 void sync(EmuTime::param time);
125 void updateTapePosition(EmuDuration::param duration, EmuTime::param time);
126 void generateRecordOutput(EmuDuration::param duration);
127
128 void fillBuf(size_t length, double x);
129 void flushOutput();
130 void autoRun();
131
132 // Schedulable
133 struct SyncEndOfTape final : Schedulable {
134 friend class CassettePlayer;
135 explicit SyncEndOfTape(Scheduler& s) : Schedulable(s) {}
136 void executeUntil(EmuTime::param time) override {
137 auto& cp = OUTER(CassettePlayer, syncEndOfTape);
138 cp.execEndOfTape(time);
139 }
140 } syncEndOfTape;
141 struct SyncAudioEmu final : Schedulable {
142 friend class CassettePlayer;
143 explicit SyncAudioEmu(Scheduler& s) : Schedulable(s) {}
144 void executeUntil(EmuTime::param time) override {
145 auto& cp = OUTER(CassettePlayer, syncAudioEmu);
146 cp.execSyncAudioEmu(time);
147 }
148 } syncAudioEmu;
149
150 void execEndOfTape(EmuTime::param time);
151 void execSyncAudioEmu(EmuTime::param time);
152 EmuTime::param getCurrentTime() const { return syncEndOfTape.getCurrentTime(); }
153
154 std::array<uint8_t, 1024> buf;
155
156 double lastX; // last unfiltered output
157 double lastY; // last filtered output
158 double partialOut;
159 double partialInterval;
160
162 EmuTime tapePos = EmuTime::zero();
163
166 EmuTime prevSyncTime = EmuTime::zero();
167
168 // SoundDevice
169 unsigned audioPos = 0;
170 Filename casImage;
171
172 MSXMotherBoard& motherBoard;
173
174 CassettePlayerCommand cassettePlayerCommand;
175
176 LoadingIndicator loadingIndicator;
177 BooleanSetting autoRunSetting;
178 std::unique_ptr<Wav8Writer> recordImage;
179 std::unique_ptr<CassetteImage> playImage;
180
181 size_t sampCnt = 0;
182 State state = State::STOP;
183 bool lastOutput = false;
184 bool motor = false, motorControl = true;
185 bool syncScheduled = false;
186};
188
189} // namespace openmsx
190
191#endif
void plugHelper(Connector &connector, EmuTime::param time) override
static constexpr std::string_view TAPE_RECORDING_DIR
const Filename & getImageName() const
bool isMotorControlEnabled() const
float getAmplificationFactorImpl() const override
Get amplification/attenuation factor for this device.
std::string_view getName() const override
Name used to identify this pluggable.
std::string_view getDescription() const override
Description for this pluggable.
double getTapePos(EmuTime::param time)
Returns the position of the tape, in seconds from the beginning of the tape.
friend class CassettePlayerCommand
void setSignal(bool output, EmuTime::param time) override
Sets the cassette output signal false = low true = high.
void unplugHelper(EmuTime::param time) override
void generateChannels(std::span< float * > buffers, unsigned num) override
Abstract method to generate the actual sound data.
void setMotor(bool status, EmuTime::param time) override
Sets the cassette motor relay false = off true = on.
void serialize(Archive &ar, unsigned version)
int16_t readSample(EmuTime::param time) override
Read wave data from cassette device.
static constexpr std::string_view TAPE_RECORDING_EXTENSION
double getTapeLength(EmuTime::param time)
Returns the length of the tape in seconds.
void getMediaInfo(TclObject &result) override
This method gets called when information is required on the media inserted in the media slot of the p...
Represents something you can plug devices into.
Definition Connector.hh:21
This class represents a filename.
Definition Filename.hh:20
Every class that wants to get scheduled at some point must inherit from this class.
Schedulable(const Schedulable &)=delete
This file implemented 3 utility functions:
Definition Autofire.cc:11
#define OUTER(type, member)
Definition outer.hh:42
#define SERIALIZE_CLASS_VERSION(CLASS, VERSION)