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 "serialize_meta.hh"
14 #include <string>
15 #include <memory>
16 
17 namespace openmsx {
18 
19 class CassetteImage;
20 class HardwareConfig;
21 class MSXMotherBoard;
22 class Wav8Writer;
23 
25  , private EventListener
26 {
27 public:
28  explicit CassettePlayer(const HardwareConfig& hwConf);
30 
31  // CassetteDevice
32  void setMotor(bool status, EmuTime::param time) override;
33  short readSample(EmuTime::param time) override;
34  void setSignal(bool output, EmuTime::param time) override;
35 
36  // Pluggable
37  const std::string& getName() const override;
38  string_ref getDescription() const override;
39  void plugHelper(Connector& connector, EmuTime::param time) override;
40  void unplugHelper(EmuTime::param time) override;
41 
42  // SoundDevice
43  void generateChannels(int** bufs, unsigned num) override;
44 
45  template<typename Archive>
46  void serialize(Archive& ar, unsigned version);
47 
48  enum State { PLAY, RECORD, STOP }; // public for serialization
49 
50 private:
51  State getState() const { return state; }
52  std::string getStateString() const;
53  void setState(State newState, const Filename& newImage,
54  EmuTime::param time);
55  void setImageName(const Filename& newImage);
56  const Filename& getImageName() const { return casImage; }
57  void checkInvariants() const;
58 
61  void playTape(const Filename& filename, EmuTime::param time);
62  void insertTape(const Filename& filename);
63 
66  void removeTape(EmuTime::param time);
67 
71  void recordTape(const Filename& filename, EmuTime::param time);
72 
77  void rewind(EmuTime::param time);
78 
81  void setMotorControl(bool status, EmuTime::param time);
82 
86  bool isRolling() const;
87 
92  void updateLoadingState(EmuTime::param time);
93 
96  double getTapePos(EmuTime::param time);
97 
102  double getTapeLength(EmuTime::param time);
103 
104  void sync(EmuTime::param time);
105  void updateTapePosition(EmuDuration::param duration, EmuTime::param time);
106  void generateRecordOutput(EmuDuration::param duration);
107 
108  void fillBuf(size_t length, double x);
109  void flushOutput();
110  void autoRun();
111 
112  // EventListener
113  int signalEvent(const std::shared_ptr<const Event>& event) override;
114 
115  // Schedulable
116  struct SyncBase : public Schedulable {
117  SyncBase(Scheduler& s, CassettePlayer& cp_)
118  : Schedulable(s), cp(cp_) {}
119  CassettePlayer& cp;
120  friend class CassettePlayer;
121  };
122  struct SyncEndOfTape : public SyncBase {
123  SyncEndOfTape(Scheduler& s, CassettePlayer& c) : SyncBase(s, c) {}
124  void executeUntil(EmuTime::param time) override {
125  cp.execEndOfTape(time);
126  }
127  } syncEndOfTape;
128  struct SyncAudioEmu : public SyncBase {
129  SyncAudioEmu(Scheduler& s, CassettePlayer& c) : SyncBase(s, c) {}
130  void executeUntil(EmuTime::param time) override {
131  cp.execSyncAudioEmu(time);
132  }
133  } syncAudioEmu;
134 
135  void execEndOfTape(EmuTime::param time);
136  void execSyncAudioEmu(EmuTime::param time);
137  EmuTime::param getCurrentTime() const { return syncEndOfTape.getCurrentTime(); }
138 
139  static const size_t BUF_SIZE = 1024;
140  unsigned char buf[BUF_SIZE];
141 
142  double lastX; // last unfiltered output
143  double lastY; // last filtered output
144  double partialOut;
145  double partialInterval;
146 
148  EmuTime tapePos;
149 
152  EmuTime prevSyncTime;
153 
154  // SoundDevice
155  unsigned audioPos;
156  Filename casImage;
157 
158  MSXMotherBoard& motherBoard;
159 
160  class TapeCommand final : public RecordedCommand {
161  public:
162  TapeCommand(CommandController& commandController,
163  StateChangeDistributor& stateChangeDistributor,
164  Scheduler& scheduler,
165  CassettePlayer& cassettePlayer);
166  void execute(array_ref<TclObject> tokens, TclObject& result,
167  EmuTime::param time) override;
168  std::string help(const std::vector<std::string>& tokens) const override;
169  void tabCompletion(std::vector<std::string>& tokens) const override;
170  bool needRecord(array_ref<TclObject> tokens) const override;
171  private:
172  CassettePlayer& cassettePlayer;
173  } tapeCommand;
174 
175  LoadingIndicator loadingIndicator;
176  BooleanSetting autoRunSetting;
177  std::unique_ptr<Wav8Writer> recordImage;
178  std::unique_ptr<CassetteImage> playImage;
179 
180  size_t sampcnt;
181  State state;
182  bool lastOutput;
183  bool motor, motorControl;
184  bool syncScheduled;
185 };
187 
188 } // namespace openmsx
189 
190 #endif
void plugHelper(Connector &connector, EmuTime::param time) override
T length(const vecN< N, T > &x)
Definition: gl_vec.hh:281
Represents something you can plug devices into.
Definition: Connector.hh:21
void generateChannels(int **bufs, unsigned num) override
Abstract method to generate the actual sound data.
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)
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.
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
const EmuTime & param
Definition: EmuTime.hh:20
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.