diff options
Diffstat (limited to 'backends/audiocd/win32/win32-audiocd.cpp')
| -rw-r--r-- | backends/audiocd/win32/win32-audiocd.cpp | 202 | 
1 files changed, 27 insertions, 175 deletions
| 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: | 
