aboutsummaryrefslogtreecommitdiff
path: root/backends/audiocd
diff options
context:
space:
mode:
Diffstat (limited to 'backends/audiocd')
-rw-r--r--backends/audiocd/audiocd-stream.cpp174
-rw-r--r--backends/audiocd/audiocd-stream.h86
-rw-r--r--backends/audiocd/linux/linux-audiocd.cpp185
-rw-r--r--backends/audiocd/win32/win32-audiocd.cpp202
4 files changed, 315 insertions, 332 deletions
diff --git a/backends/audiocd/audiocd-stream.cpp b/backends/audiocd/audiocd-stream.cpp
new file mode 100644
index 0000000000..da55654a1d
--- /dev/null
+++ b/backends/audiocd/audiocd-stream.cpp
@@ -0,0 +1,174 @@
+/* Cabal - Legacy Game Implementations
+ *
+ * Cabal is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/audiocd/audiocd-stream.h"
+#include "common/textconsole.h"
+
+AudioCDStream::AudioCDStream() : _buffer(), _frame(0), _bufferPos(0), _bufferFrame(0), _forceStop(false) {
+}
+
+AudioCDStream::~AudioCDStream() {
+ // Stop the timer; the subclass needs to do this,
+ // so this is just a last resort.
+ stopTimer();
+
+ // Clear any buffered frames
+ emptyQueue();
+}
+
+int AudioCDStream::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 AudioCDStream::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 AudioCDStream::endOfData() const {
+ return !shouldForceStop() && getStartFrame() + _frame >= getEndFrame() && _bufferPos == kSamplesPerFrame;
+}
+
+bool AudioCDStream::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;
+
+ // Start the timer again
+ startTimer();
+ return true;
+}
+
+Audio::Timestamp AudioCDStream::getLength() const {
+ return Audio::Timestamp(0, getEndFrame() - getStartFrame(), kFramesPerSecond);
+}
+
+void AudioCDStream::timerProc(void *refCon) {
+ static_cast<AudioCDStream *>(refCon)->onTimer();
+}
+
+void AudioCDStream::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 (shouldForceStop() || getStartFrame() + _bufferFrame >= getEndFrame())
+ 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 (!shouldForceStop() && queueCount < kBufferThreshold && getStartFrame() + _bufferFrame < getEndFrame()) {
+ int16 *buffer = new int16[kSamplesPerFrame];
+
+ // Figure out the MSF of the frame we're looking for
+ int frame = _bufferFrame + getStartFrame();
+
+ // Request to read that frame
+ if (!readFrame(frame, buffer)) {
+ warning("Failed to read CD audio");
+ forceStop();
+ return;
+ }
+
+ _bufferFrame++;
+
+ // Now push the buffer onto the queue
+ Common::StackLock lock(_mutex);
+ _bufferQueue.push(buffer);
+ queueCount = _bufferQueue.size();
+ }
+}
+
+void AudioCDStream::startTimer() {
+ _forceStop = false;
+ g_system->getTimerManager()->installTimerProc(timerProc, 10 * 1000, this, "AudioCDStream");
+}
+
+void AudioCDStream::stopTimer() {
+ forceStop();
+ g_system->getTimerManager()->removeTimerProc(timerProc);
+}
+
+void AudioCDStream::emptyQueue() {
+ while (!_bufferQueue.empty())
+ delete[] _bufferQueue.pop();
+}
+
+bool AudioCDStream::shouldForceStop() const {
+ Common::StackLock lock(_forceStopMutex);
+ return _forceStop;
+}
+
+void AudioCDStream::forceStop() {
+ Common::StackLock lock(_forceStopMutex);
+ _forceStop = true;
+}
diff --git a/backends/audiocd/audiocd-stream.h b/backends/audiocd/audiocd-stream.h
new file mode 100644
index 0000000000..a8938025b6
--- /dev/null
+++ b/backends/audiocd/audiocd-stream.h
@@ -0,0 +1,86 @@
+/* Cabal - Legacy Game Implementations
+ *
+ * Cabal is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_AUDIOCD_AUDIOCD_STREAM_H
+#define BACKENDS_AUDIOCD_AUDIOCD_STREAM_H
+
+#include "audio/audiostream.h"
+#include "common/mutex.h"
+#include "common/queue.h"
+#include "common/timer.h"
+
+class AudioCDStream : public Audio::SeekableAudioStream {
+public:
+ AudioCDStream();
+ ~AudioCDStream();
+
+ 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:
+ virtual uint getStartFrame() const = 0;
+ virtual uint getEndFrame() const = 0;
+ virtual bool readFrame(int frame, int16 *buffer) = 0;
+
+ void startTimer();
+ void stopTimer();
+
+ enum {
+ kBytesPerFrame = 2352,
+ kSamplesPerFrame = kBytesPerFrame / 2
+ };
+
+ enum {
+ kSecondsPerMinute = 60,
+ kFramesPerSecond = 75
+ };
+
+ enum {
+ // Keep about a second's worth of audio in the buffer
+ kBufferThreshold = kFramesPerSecond
+ };
+
+private:
+ int16 _buffer[kSamplesPerFrame];
+ int _frame;
+ uint _bufferPos;
+
+ Common::Queue<int16 *> _bufferQueue;
+ int _bufferFrame;
+ Common::Mutex _mutex;
+
+ bool _forceStop;
+ bool shouldForceStop() const;
+ void forceStop();
+ Common::Mutex _forceStopMutex;
+
+ bool readNextFrame();
+ static void timerProc(void *refCon);
+ void onTimer();
+ void emptyQueue();
+};
+
+#endif
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:
diff --git a/backends/audiocd/win32/win32-audiocd.cpp b/backends/audiocd/win32/win32-audiocd.cpp
index e3fdcf6477..0b04a7ca5d 100644
--- a/backends/audiocd/win32/win32-audiocd.cpp
+++ b/backends/audiocd/win32/win32-audiocd.cpp
@@ -23,6 +23,7 @@
#include "backends/audiocd/win32/win32-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"
@@ -43,29 +44,10 @@
#endif
enum {
- kLeadoutTrack = 0xAA
-};
-
-enum {
- kBytesPerFrame = 2352,
- kSamplesPerFrame = kBytesPerFrame / 2
-};
-
-enum {
- kSecondsPerMinute = 60,
- kFramesPerSecond = 75
-};
-
-enum {
// The CD-ROM pre-gap is 2s
kPreGapFrames = kFramesPerSecond * 2
};
-enum {
- // Keep about a second's worth of audio in the buffer
- kBufferThreshold = kFramesPerSecond
-};
-
static int getFrameCount(const TRACK_DATA &data) {
int time = data.Address[1];
time *= kSecondsPerMinute;
@@ -75,35 +57,19 @@ static int getFrameCount(const TRACK_DATA &data) {
return time;
}
-class Win32AudioCDStream : public Audio::SeekableAudioStream {
+class Win32AudioCDStream : public AudioCDStream {
public:
Win32AudioCDStream(HANDLE handle, const TRACK_DATA &startEntry, const TRACK_DATA &endEntry);
~Win32AudioCDStream();
- 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:
HANDLE _driveHandle;
const TRACK_DATA &_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();
};
Win32AudioCDStream::Win32AudioCDStream(HANDLE handle, const TRACK_DATA &startEntry, const TRACK_DATA &endEntry) :
@@ -113,150 +79,36 @@ Win32AudioCDStream::Win32AudioCDStream(HANDLE handle, const TRACK_DATA &startEnt
Win32AudioCDStream::~Win32AudioCDStream() {
stopTimer();
- emptyQueue();
-}
-
-int Win32AudioCDStream::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 Win32AudioCDStream::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 Win32AudioCDStream::endOfData() const {
- return getFrameCount(_startEntry) + _frame >= getFrameCount(_endEntry) && _bufferPos == kSamplesPerFrame;
-}
-
-bool Win32AudioCDStream::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;
-
- // Start the timer again
- startTimer();
- return true;
}
-Audio::Timestamp Win32AudioCDStream::getLength() const {
- return Audio::Timestamp(0, getFrameCount(_endEntry) - getFrameCount(_startEntry), 75);
+uint Win32AudioCDStream::getStartFrame() const {
+ return getFrameCount(_startEntry);
}
-void Win32AudioCDStream::timerProc(void *refCon) {
- static_cast<Win32AudioCDStream *>(refCon)->onTimer();
-}
-
-void Win32AudioCDStream::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) + _bufferFrame >= getFrameCount(_endEntry))
- 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) + _bufferFrame < getFrameCount(_endEntry)) {
- int16 *buffer = new int16[kSamplesPerFrame];
-
- // Figure out the MSF of the frame we're looking for
- int frame = _bufferFrame + getFrameCount(_startEntry);
-
- // Request to read that frame
- RAW_READ_INFO readAudio;
- memset(&readAudio, 0, sizeof(readAudio));
- readAudio.DiskOffset.QuadPart = (frame - kPreGapFrames) * 2048;
- readAudio.SectorCount = 1;
- readAudio.TrackMode = CDDA;
-
- DWORD bytesReturned;
- bool result = DeviceIoControl(
- _driveHandle,
- IOCTL_CDROM_RAW_READ,
- &readAudio,
- sizeof(readAudio),
- buffer,
- kBytesPerFrame,
- &bytesReturned,
- NULL);
- if (!result) {
- warning("Failed to retrieve CD sector %d: %d", frame, (int)GetLastError());
- _bufferFrame = getFrameCount(_endEntry) - getFrameCount(_startEntry);
- return;
- }
-
- _bufferFrame++;
-
- // Now push the buffer onto the queue
- Common::StackLock lock(_mutex);
- _bufferQueue.push(buffer);
- queueCount = _bufferQueue.size();
- }
+uint Win32AudioCDStream::getEndFrame() const {
+ return getFrameCount(_endFrame);
}
-void Win32AudioCDStream::startTimer() {
- g_system->getTimerManager()->installTimerProc(timerProc, 10 * 1000, this, "Win32AudioCDStream");
-}
+bool Win32AudioCDStream::readFrame(int frame, int16 *buffer) {
+ // Request to read that frame
+ RAW_READ_INFO readAudio;
+ memset(&readAudio, 0, sizeof(readAudio));
+ readAudio.DiskOffset.QuadPart = (frame - kPreGapFrames) * 2048;
+ readAudio.SectorCount = 1;
+ readAudio.TrackMode = CDDA;
-void Win32AudioCDStream::stopTimer() {
- g_system->getTimerManager()->removeTimerProc(timerProc);
+ DWORD bytesReturned;
+ return DeviceIoControl(
+ _driveHandle,
+ IOCTL_CDROM_RAW_READ,
+ &readAudio,
+ sizeof(readAudio),
+ buffer,
+ kBytesPerFrame,
+ &bytesReturned,
+ NULL);
}
-void Win32AudioCDStream::emptyQueue() {
- while (!_bufferQueue.empty())
- delete[] _bufferQueue.pop();
-}
class Win32AudioCDManager : public DefaultAudioCDManager {
public: