aboutsummaryrefslogtreecommitdiff
path: root/backends/audiocd/linux/linux-audiocd.cpp
diff options
context:
space:
mode:
authorMatthew Hoops2015-10-16 08:36:16 -0400
committerJohannes Schickel2016-03-13 13:57:24 +0100
commit41a1dcb0bb8bd7aaa20d03ea92aa49210b66fa92 (patch)
treea9999f4d8c05623551ebb7b37b4deafb32082aad /backends/audiocd/linux/linux-audiocd.cpp
parentaa6ff444408bfd17bcca1d8364e86ce62da327ef (diff)
downloadscummvm-rg350-41a1dcb0bb8bd7aaa20d03ea92aa49210b66fa92.tar.gz
scummvm-rg350-41a1dcb0bb8bd7aaa20d03ea92aa49210b66fa92.tar.bz2
scummvm-rg350-41a1dcb0bb8bd7aaa20d03ea92aa49210b66fa92.zip
BACKENDS: Switch to a common base class for threaded audio CD streams
Diffstat (limited to 'backends/audiocd/linux/linux-audiocd.cpp')
-rw-r--r--backends/audiocd/linux/linux-audiocd.cpp185
1 files changed, 28 insertions, 157 deletions
diff --git a/backends/audiocd/linux/linux-audiocd.cpp b/backends/audiocd/linux/linux-audiocd.cpp
index a835ade218..ea5eb1f9be 100644
--- a/backends/audiocd/linux/linux-audiocd.cpp
+++ b/backends/audiocd/linux/linux-audiocd.cpp
@@ -29,15 +29,12 @@
#include "backends/audiocd/linux/linux-audiocd.h"
-#include "audio/audiostream.h"
+#include "backends/audiocd/audiocd-stream.h"
#include "backends/audiocd/default/default-audiocd.h"
#include "common/array.h"
#include "common/config-manager.h"
-#include "common/mutex.h"
-#include "common/queue.h"
#include "common/str.h"
#include "common/debug.h"
-#include "common/timer.h"
enum {
kLeadoutTrack = 0xAA
@@ -67,185 +64,59 @@ static int getFrameCount(const cdrom_msf0 &msf) {
return time;
}
-class LinuxAudioCDStream : public Audio::SeekableAudioStream {
+class LinuxAudioCDStream : public AudioCDStream {
public:
LinuxAudioCDStream(int fd, const cdrom_tocentry &startEntry, const cdrom_tocentry &endEntry);
~LinuxAudioCDStream();
- int readBuffer(int16 *buffer, const int numSamples);
- bool isStereo() const { return true; }
- int getRate() const { return 44100; }
- bool endOfData() const;
- bool seek(const Audio::Timestamp &where);
- Audio::Timestamp getLength() const;
+protected:
+ uint getStartFrame() const;
+ uint getEndFrame() const;
+ bool readFrame(int frame, int16 *buffer);
private:
int _fd;
const cdrom_tocentry &_startEntry, &_endEntry;
- int16 _buffer[kSamplesPerFrame];
- int _frame;
- uint _bufferPos;
-
- Common::Queue<int16 *> _bufferQueue;
- int _bufferFrame;
- Common::Mutex _mutex;
-
- bool readNextFrame();
- static void timerProc(void *refCon);
- void onTimer();
- void emptyQueue();
- void startTimer();
- void stopTimer();
};
LinuxAudioCDStream::LinuxAudioCDStream(int fd, const cdrom_tocentry &startEntry, const cdrom_tocentry &endEntry) :
- _fd(fd), _startEntry(startEntry), _endEntry(endEntry), _buffer(), _frame(0), _bufferPos(kSamplesPerFrame), _bufferFrame(0) {
+ _fd(fd), _startEntry(startEntry), _endEntry(endEntry) {
startTimer();
}
LinuxAudioCDStream::~LinuxAudioCDStream() {
stopTimer();
- emptyQueue();
}
-int LinuxAudioCDStream::readBuffer(int16 *buffer, const int numSamples) {
- int samples = 0;
-
- // See if any data is left first
- while (_bufferPos < kSamplesPerFrame && samples < numSamples)
- buffer[samples++] = _buffer[_bufferPos++];
-
- // Bail out if done
- if (endOfData())
- return samples;
-
- while (samples < numSamples && !endOfData()) {
- if (!readNextFrame())
- return samples;
-
- // Copy the samples over
- for (_bufferPos = 0; _bufferPos < kSamplesPerFrame && samples < numSamples; )
- buffer[samples++] = _buffer[_bufferPos++];
- }
-
- return samples;
-}
-
-bool LinuxAudioCDStream::readNextFrame() {
- // Fetch a frame from the queue
- int16 *buffer;
-
- {
- Common::StackLock lock(_mutex);
-
- // Nothing we can do if it's empty
- if (_bufferQueue.empty())
- return false;
-
- buffer = _bufferQueue.pop();
- }
-
- memcpy(_buffer, buffer, kSamplesPerFrame * 2);
- delete[] buffer;
- _frame++;
- return true;
-}
-
-bool LinuxAudioCDStream::endOfData() const {
- return getFrameCount(_startEntry.cdte_addr.msf) + _frame >= getFrameCount(_endEntry.cdte_addr.msf) && _bufferPos == kSamplesPerFrame;
-}
-
-bool LinuxAudioCDStream::seek(const Audio::Timestamp &where) {
- // Stop the timer
- stopTimer();
-
- // Clear anything out of the queue
- emptyQueue();
-
- // Convert to the frame number
- // Really not much else needed
- _bufferPos = kSamplesPerFrame;
- _frame = where.convertToFramerate(kFramesPerSecond).totalNumberOfFrames();
- _bufferFrame = _frame;
+bool LinuxAudioCDStream::readFrame(int frame, int16 *buffer) {
+ int seconds = frame / kFramesPerSecond;
+ frame %= kFramesPerSecond;
+ int minutes = seconds / kSecondsPerMinute;
+ seconds %= kSecondsPerMinute;
+
+ // Request to read that frame
+ cdrom_read_audio readAudio;
+ readAudio.addr.msf.minute = minutes;
+ readAudio.addr.msf.second = seconds;
+ readAudio.addr.msf.frame = frame;
+ readAudio.addr_format = CDROM_MSF;
+ readAudio.nframes = 1;
+ readAudio.buf = reinterpret_cast<__u8*>(buffer);
+
+ if (ioctl(_fd, CDROMREADAUDIO, &readAudio) < 0)
+ return false;
- // Start the timer again
- startTimer();
return true;
}
-Audio::Timestamp LinuxAudioCDStream::getLength() const {
- return Audio::Timestamp(0, getFrameCount(_endEntry.cdte_addr.msf) - getFrameCount(_startEntry.cdte_addr.msf), 75);
+uint LinuxAudioCDStream::getStartFrame() const {
+ return getFrameCount(_startEntry.cdte_addr.msf);
}
-void LinuxAudioCDStream::timerProc(void *refCon) {
- static_cast<LinuxAudioCDStream *>(refCon)->onTimer();
+uint LinuxAudioCDStream::getEndFrame() const {
+ return getFrameCount(_endEntry.cdte_addr.msf);
}
-void LinuxAudioCDStream::onTimer() {
- // The goal here is to do as much work in this timer instead
- // of doing it in the readBuffer() call, which is the mixer.
-
- // If we're done, bail.
- if (getFrameCount(_startEntry.cdte_addr.msf) + _bufferFrame >= getFrameCount(_endEntry.cdte_addr.msf))
- return;
-
- // Get a quick count of the number of items in the queue
- // We don't care that much; we only need a quick estimate
- _mutex.lock();
- uint32 queueCount = _bufferQueue.size();
- _mutex.unlock();
-
- // If we have enough audio buffered, bail out
- if (queueCount >= kBufferThreshold)
- return;
-
- while (queueCount < kBufferThreshold && getFrameCount(_startEntry.cdte_addr.msf) + _bufferFrame < getFrameCount(_endEntry.cdte_addr.msf)) {
- int16 *buffer = new int16[kSamplesPerFrame];
-
- // Figure out the MSF of the frame we're looking for
- int frame = _bufferFrame + getFrameCount(_startEntry.cdte_addr.msf);
-
- int seconds = frame / kFramesPerSecond;
- frame %= kFramesPerSecond;
- int minutes = seconds / kSecondsPerMinute;
- seconds %= kSecondsPerMinute;
-
- // Request to read that frame
- cdrom_read_audio readAudio;
- readAudio.addr.msf.minute = minutes;
- readAudio.addr.msf.second = seconds;
- readAudio.addr.msf.frame = frame;
- readAudio.addr_format = CDROM_MSF;
- readAudio.nframes = 1;
- readAudio.buf = reinterpret_cast<__u8*>(buffer);
-
- if (ioctl(_fd, CDROMREADAUDIO, &readAudio) < 0) {
- warning("Failed to read audio");
- _bufferFrame = getFrameCount(_endEntry.cdte_addr.msf);
- return;
- }
-
- _bufferFrame++;
-
- // Now push the buffer onto the queue
- Common::StackLock lock(_mutex);
- _bufferQueue.push(buffer);
- queueCount = _bufferQueue.size();
- }
-}
-
-void LinuxAudioCDStream::startTimer() {
- g_system->getTimerManager()->installTimerProc(timerProc, 10 * 1000, this, "LinuxAudioCDStream");
-}
-
-void LinuxAudioCDStream::stopTimer() {
- g_system->getTimerManager()->removeTimerProc(timerProc);
-}
-
-void LinuxAudioCDStream::emptyQueue() {
- while (!_bufferQueue.empty())
- delete[] _bufferQueue.pop();
-}
class LinuxAudioCDManager : public DefaultAudioCDManager {
public: