diff options
| -rw-r--r-- | backends/audiocd/audiocd-stream.cpp | 174 | ||||
| -rw-r--r-- | backends/audiocd/audiocd-stream.h | 86 | ||||
| -rw-r--r-- | backends/audiocd/linux/linux-audiocd.cpp | 185 | ||||
| -rw-r--r-- | backends/audiocd/win32/win32-audiocd.cpp | 202 | ||||
| -rw-r--r-- | backends/module.mk | 1 | 
5 files changed, 316 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: diff --git a/backends/module.mk b/backends/module.mk index 8abab65f14..3f7620e2a8 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -3,6 +3,7 @@ MODULE := backends  MODULE_OBJS := \  	base-backend.o \  	modular-backend.o \ +	audiocd/audiocd-stream.o \  	audiocd/default/default-audiocd.o \  	events/default/default-events.o \  	fs/abstract-fs.o \ | 
