Discman
Loading...
Searching...
No Matches
cd_drive.h
Go to the documentation of this file.
1
6
7#ifndef CD_DRIVE_H
8#define CD_DRIVE_H
9
10#define READ_END 0
11#define WRITE_END 1
12
13#include <stdint.h>
14#include <thread>
15#include <mutex>
16#include <iostream>
17#include <sstream>
18#include <string>
19#include <vector>
20#include <string.h>
21#include <cdio/paranoia/paranoia.h>
22#include <cdio/cd_types.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/wait.h>
27#include <sys/ioctl.h>
28#include <linux/cdrom.h>
29#include <sigc++/signal.h>
30#include <climits>
31#include <chrono>
32
34
35const auto __open = open;
36
39class CDDrive : public Producer<int16_t> {
40
41 public:
42 static constexpr int BUFFER_SIZE_PLAYING = 2048;
43 static constexpr int BUFFER_SIZE_RIPPING = 512;
44
45 static constexpr int SAMPLE_RATE = 44100;
46
48 typedef sigc::signal<void()> sig_eject;
49
52 struct DriveErrorException : public std::exception {
53 const char* what() const throw() {
54 return "CD-ROM drive could not be identified.";
55 }
56 };
57
59 struct NoDiscPresentException : public std::exception {
60 const char* what() const throw() {
61 return "No disc present.";
62 }
63 };
64
67 struct DiscErrorException : public std::exception {
68 const char* what() const throw() {
69 return "Could not open disc.";
70 }
71 };
72
74 CDDrive();
75
77 ~CDDrive();
78
79 bool present() const;
80
83 void eject();
84
85 unsigned int tracks() const;
86
87 void track(const int track);
88 unsigned int track() const;
89
91 lba_t lba(const track_t track) const;
92
93 float elapsed();
94 float progress();
95 unsigned int seconds() const;
96
99 void resize_buffer(unsigned int sectors);
100
104 int16_t next() override;
105
108 void register_consumer(const Consumer<int16_t>* const) = delete;
109
112 int16_t next_for_consumer(const Consumer<int16_t>* const) = delete;
113
115 bool done();
116
118
119 private:
120
122 static constexpr int BYTES_PER_SAMPLE = sizeof(int16_t);
123
126
129
130 bool identify();
131 void open();
132 void update_track(const unsigned int track);
133
136 static std::vector<std::string> devices();
137
138 class Reader;
139 class Poller;
140
141 std::string _device;
142 cdrom_drive_t* _drive;
145
153 int16_t* _buffers[2];
154
155 uint8_t _buffer;
156 unsigned int _buffer_idx;
157
158 unsigned int _track;
159 unsigned int _cursor;
160 unsigned int _end;
161
164 std::mutex _load_lock;
165
168 std::mutex _cursor_lock;
169};
170
173 public:
174
182
185 Reader(CDDrive& drive);
186
188 ~Reader();
189
192 void action(const Action action);
193
196 Action action();
197
200 void track(const int track);
201
204 void buffer(const int buffer);
205
206 void load();
207 void loop();
208
209 private:
211
213
215
216 cdrom_paranoia_t* _paranoia;
217
220 std::mutex _action_lock;
221
222
224 std::thread _thread;
225};
226
229 public:
232 Poller(CDDrive& drive);
233
235 ~Poller();
236
237 void poll();
238
239 private:
241
242 bool _exit;
243
246 std::mutex _exit_lock;
247
249 std::thread _thread;
250};
251
252#endif // CD_DRIVE_H
const auto __open
Definition cd_drive.h:35
The Poller uses a separate thread to poll the host for a disc drive with an audio CD.
Definition cd_drive.h:228
Poller(CDDrive &drive)
Poller constructor.
Definition cd_drive.cc:98
std::mutex _exit_lock
Provides mutually exclusive access to the _exit member between the the application thread and the Pol...
Definition cd_drive.h:246
bool _exit
Stores a request to exit poll().
Definition cd_drive.h:242
~Poller()
Poller destructor.
Definition cd_drive.cc:104
std::thread _thread
The thread used to run poll().
Definition cd_drive.h:249
void poll()
The execution loop performed by the thread.
Definition cd_drive.cc:111
CDDrive & _drive
The parent CDDrive.
Definition cd_drive.h:240
The Reader uses a separate thread to load data into the CDDrive's ring buffer.
Definition cd_drive.h:172
Action
Actions are taken consecutively. Setting an action on the Reader takes effect after its current actio...
Definition cd_drive.h:177
void buffer(const int buffer)
Sets the index of the buffer in the CDDrive's ring buffer to read samples into.
Definition cd_drive.cc:38
Action _action
The current or next action to be taken by the Reader.
Definition cd_drive.h:212
std::thread _thread
The thread used to run loop().
Definition cd_drive.h:224
void loop()
The execution loop performed by the thread.
Definition cd_drive.cc:77
cdrom_paranoia_t * _paranoia
cdio handle to the sample reader.
Definition cd_drive.h:216
void load()
Fills the current buffer with audio samples.
Definition cd_drive.cc:61
CDDrive & _drive
The parent CDDrive.
Definition cd_drive.h:210
Reader(CDDrive &drive)
Reader constructor.
Definition cd_drive.cc:9
int _buffer
The index of the buffer in the CDDrive's ring buffer to read samples into.
Definition cd_drive.h:214
~Reader()
Reader destructor.
Definition cd_drive.cc:19
Action action()
Returns the current Reader action in a thread-safe way.
Definition cd_drive.cc:42
std::mutex _action_lock
Provides mutually exclusive access to the _action member between the the application thread and the R...
Definition cd_drive.h:220
int16_t * _buffers[2]
A ring buffer of size 2. One buffer has new audio samples written to it. When that buffer is full,...
Definition cd_drive.h:153
std::mutex _load_lock
Provides mutually exclusive access to the drive and audio buffers between the application thread and ...
Definition cd_drive.h:164
Poller * _poller
Used to poll for the first openable disc drive.
Definition cd_drive.h:144
void update_track(const unsigned int track)
Sets the current disc track using 1-based indexing.
Definition cd_drive.cc:296
float progress()
The percentage completion of the rip of the current track (0.0 - 1.0).
Definition cd_drive.cc:340
bool present() const
Returns whether a disc is in the drive.
Definition cd_drive.cc:157
void eject()
Ejects the disc in the drive.
Definition cd_drive.cc:161
unsigned int _end
The 0-based index just past the end of the read buffer.
Definition cd_drive.h:160
void track(const int track)
Sets the current track to the given 1-based index.
Definition cd_drive.cc:312
~CDDrive()
CDDrive destructor.
Definition cd_drive.cc:146
sigc::signal< void()> sig_eject
"Eject requested" signal type.
Definition cd_drive.h:48
lba_t lba(const track_t track) const
Returns the LBA (large block address) of the start of the given track on the disc.
Definition cd_drive.cc:348
unsigned int _cursor
The 0-based index into the read buffer.
Definition cd_drive.h:159
void register_consumer(const Consumer< int16_t > *const)=delete
Deleted. This Producer does not support multiple Consumers.
cdrom_drive_t * _drive
A cdio handle to the disc drive.
Definition cd_drive.h:142
bool identify()
Finds a disc drive on the host with an audio disc inside.
Definition cd_drive.cc:251
bool done()
Whether the current track has been played or ripped through.
Definition cd_drive.cc:358
static constexpr int BUFFER_SIZE_PLAYING
The audio buffer size when playing, in CD audio frames.
Definition cd_drive.h:42
uint8_t _buffer
The 0-based index of the buffer in the ring currently designated as the write buffer.
Definition cd_drive.h:155
unsigned int _buffer_idx
The 0-based index into the write buffer.
Definition cd_drive.h:156
int16_t next() override
Provides the next audio sample from the current track. This is one half of an audio frame which conta...
Definition cd_drive.cc:364
std::string _device
The path to the device node of the disc drive.
Definition cd_drive.h:141
unsigned int seconds() const
The duration of the entire disc in whole seconds.
Definition cd_drive.cc:354
int _bufferSamples
The number of audio samples (one half of an audio frame) in the audio buffer.
Definition cd_drive.h:128
float elapsed()
The elapsed duration of the track in fractional seconds.
Definition cd_drive.cc:330
int16_t next_for_consumer(const Consumer< int16_t > *const)=delete
Deleted. This Producer does not support multiple Consumers.
int _bufferSectors
The number of CD frames in the audio buffer.
Definition cd_drive.h:127
CDDrive()
CDDrive constructor.
Definition cd_drive.cc:130
static constexpr int BUFFER_SIZE_RIPPING
The audio buffer size when ripping, in CD audio frames.
Definition cd_drive.h:43
sig_eject _sig_eject
Emitted when the disc is successfully ejected.
Definition cd_drive.h:125
static constexpr int BYTES_PER_SAMPLE
The number of bytes in one CD audio sample (an int16_t).
Definition cd_drive.h:122
std::mutex _cursor_lock
Provides mutually exclusive access to the track cursor between the the application thread and the Por...
Definition cd_drive.h:168
static constexpr int SAMPLE_RATE
CD audio sample rate.
Definition cd_drive.h:45
sig_eject signal_eject()
Getter for ::_signal_eject.
Definition cd_drive.cc:292
void open()
Opens the disc for reading.
Definition cd_drive.cc:282
static std::vector< std::string > devices()
Returns the paths of device nodes corresponding to disc drives with discs that can be opened.
Definition cd_drive.cc:179
unsigned int _track
The current track being played or ripped.
Definition cd_drive.h:158
void resize_buffer(unsigned int sectors)
Resizes the audio buffer.
Definition cd_drive.cc:50
Reader * _reader
Used to read audio samples into the audio buffer.
Definition cd_drive.h:143
unsigned int tracks() const
Returns the number of tracks on the disc.
Definition cd_drive.cc:306
unsigned int track() const
Returns the 1-based index of the current track.
Definition cd_drive.cc:326
The Consumer interface.
Definition consumer.h:15
The Producer interface.
Definition producer.h:16
Thrown when the audio CD was recognized but could not be opened for reading.
Definition cd_drive.h:67
const char * what() const
Definition cd_drive.h:68
Thrown when an audio CD was internally expected in the disc drive but could not be recognized.
Definition cd_drive.h:52
const char * what() const
Definition cd_drive.h:53
Called when the presumption that a disc is present is false.
Definition cd_drive.h:59
const char * what() const
Definition cd_drive.h:60