openMSX
CassettePlayer.hh
Go to the documentation of this file.
1 #ifndef CASSETTEPLAYER_HH
2 #define CASSETTEPLAYER_HH
3 
4 #include "EventListener.hh"
5 #include "CassetteDevice.hh"
7 #include "RecordedCommand.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 <string>
16 #include <memory>
17 
18 namespace openmsx {
19 
20 class CassetteImage;
21 class HardwareConfig;
22 class MSXMotherBoard;
23 class Wav8Writer;
24 
26  , private EventListener
27 {
28 public:
29  explicit CassettePlayer(const HardwareConfig& hwConf);
31 
32  // CassetteDevice
33  void setMotor(bool status, EmuTime::param time) override;
34  short readSample(EmuTime::param time) override;
35  void setSignal(bool output, EmuTime::param time) override;
36 
37  // Pluggable
38  const std::string& getName() const override;
39  string_ref getDescription() const override;
40  void plugHelper(Connector& connector, EmuTime::param time) override;
41  void unplugHelper(EmuTime::param time) override;
42 
43  // SoundDevice
44  void generateChannels(int** bufs, unsigned num) override;
45 
46  template<typename Archive>
47  void serialize(Archive& ar, unsigned version);
48 
49  enum State { PLAY, RECORD, STOP }; // public for serialization
50 
51 private:
52  State getState() const { return state; }
53  std::string getStateString() const;
54  void setState(State newState, const Filename& newImage,
55  EmuTime::param time);
56  void setImageName(const Filename& newImage);
57  const Filename& getImageName() const { return casImage; }
58  void checkInvariants() const;
59 
62  void playTape(const Filename& filename, EmuTime::param time);
63  void insertTape(const Filename& filename);
64 
67  void removeTape(EmuTime::param time);
68 
72  void recordTape(const Filename& filename, EmuTime::param time);
73 
78  void rewind(EmuTime::param time);
79 
82  void setMotorControl(bool status, EmuTime::param time);
83 
87  bool isRolling() const;
88 
93  void updateLoadingState(EmuTime::param time);
94 
97  double getTapePos(EmuTime::param time);
98 
103  double getTapeLength(EmuTime::param time);
104 
105  void sync(EmuTime::param time);
106  void updateTapePosition(EmuDuration::param duration, EmuTime::param time);
107  void generateRecordOutput(EmuDuration::param duration);
108 
109  void fillBuf(size_t length, double x);
110  void flushOutput();
111  void autoRun();
112 
113  // EventListener
114  int signalEvent(const std::shared_ptr<const Event>& event) override;
115 
116  // Schedulable
117  struct SyncEndOfTape : Schedulable {
118  friend class CassettePlayer;
119  SyncEndOfTape(Scheduler& s) : Schedulable(s) {}
120  void executeUntil(EmuTime::param time) override {
121  auto& cp = OUTER(CassettePlayer, syncEndOfTape);
122  cp.execEndOfTape(time);
123  }
124  } syncEndOfTape;
125  struct SyncAudioEmu : Schedulable {
126  friend class CassettePlayer;
127  SyncAudioEmu(Scheduler& s) : Schedulable(s) {}
128  void executeUntil(EmuTime::param time) override {
129  auto& cp = OUTER(CassettePlayer, syncAudioEmu);
130  cp.execSyncAudioEmu(time);
131  }
132  } syncAudioEmu;
133 
134  void execEndOfTape(EmuTime::param time);
135  void execSyncAudioEmu(EmuTime::param time);
136  EmuTime::param getCurrentTime() const { return syncEndOfTape.getCurrentTime(); }
137 
138  static const size_t BUF_SIZE = 1024;
139  unsigned char buf[BUF_SIZE];
140 
141  double lastX; // last unfiltered output
142  double lastY; // last filtered output
143  double partialOut;
144  double partialInterval;
145 
147  EmuTime tapePos;
148 
151  EmuTime prevSyncTime;
152 
153  // SoundDevice
154  unsigned audioPos;
155  Filename casImage;
156 
157  MSXMotherBoard& motherBoard;
158 
159  struct TapeCommand final : RecordedCommand {
160  TapeCommand(CommandController& commandController,
161  StateChangeDistributor& stateChangeDistributor,
162  Scheduler& scheduler);
163  void execute(array_ref<TclObject> tokens, TclObject& result,
164  EmuTime::param time) override;
165  std::string help(const std::vector<std::string>& tokens) const override;
166  void tabCompletion(std::vector<std::string>& tokens) const override;
167  bool needRecord(array_ref<TclObject> tokens) const override;
168  } tapeCommand;
169 
170  LoadingIndicator loadingIndicator;
171  BooleanSetting autoRunSetting;
172  std::unique_ptr<Wav8Writer> recordImage;
173  std::unique_ptr<CassetteImage> playImage;
174 
175  size_t sampcnt;
176  State state;
177  bool lastOutput;
178  bool motor, motorControl;
179  bool syncScheduled;
180 };
182 
183 } // namespace openmsx
184 
185 #endif
void plugHelper(Connector &connector, EmuTime::param time) override
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:322
Represents something you can plug devices into.
Definition: Connector.hh:20
void generateChannels(int **bufs, unsigned num) override
Abstract method to generate the actual sound data.
Commands that directly influence the MSX state should send and events so that they can be recorded by...
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
void serialize(Archive &ar, unsigned version)
CassettePlayer(const HardwareConfig &hwConf)
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:33
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
SERIALIZE_CLASS_VERSION(CassettePlayer, 2)
void setMotor(bool status, EmuTime::param time) override
Sets the cassette motor relay false = off true = on.
This class represents a filename.
Definition: Filename.hh:17
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void unplugHelper(EmuTime::param time) override
string_ref getDescription() const override
Description for this pluggable.
void setSignal(bool output, EmuTime::param time) override
Sets the cassette output signal false = low true = high.
short readSample(EmuTime::param time) override
Read wave data from cassette device.
const std::string & getName() const override
Name used to identify this pluggable.
Used by a device to indicate when it is loading.
#define OUTER(type, member)
Definition: outer.hh:38