[Scummvm-cvs-logs] SF.net SVN: scummvm: [25757] scummvm/trunk/sound

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Wed Feb 21 00:40:47 CET 2007


Revision: 25757
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25757&view=rev
Author:   fingolfin
Date:     2007-02-20 15:40:46 -0800 (Tue, 20 Feb 2007)

Log Message:
-----------
Revamed the Ogg Vorbis & FLAC DigitalTrackInfo subclasses to work similar to the MP3 one (i.e. only open the data file when about to play)

Modified Paths:
--------------
    scummvm/trunk/sound/flac.cpp
    scummvm/trunk/sound/mp3.cpp
    scummvm/trunk/sound/vorbis.cpp

Modified: scummvm/trunk/sound/flac.cpp
===================================================================
--- scummvm/trunk/sound/flac.cpp	2007-02-20 22:18:48 UTC (rev 25756)
+++ scummvm/trunk/sound/flac.cpp	2007-02-20 23:40:46 UTC (rev 25757)
@@ -874,41 +874,57 @@
 
 class FlacTrackInfo : public DigitalTrackInfo {
 private:
-	File *_file;
-	FlacInputStream *_firstStream; // avoid having to open the Stream twice the first time
+	Common::String _filename;
+	bool _errorFlag;
 
 public:
-	FlacTrackInfo(File *file);
-	~FlacTrackInfo();
-	bool error() { return _file == NULL; }
+	FlacTrackInfo(const char *filename);
+	bool error() { return _errorFlag; }
 	void play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration);
 };
 
-FlacTrackInfo::FlacTrackInfo(File *file) : _file(NULL), _firstStream(NULL) {
-	FlacInputStream *tempStream = new FlacInputStream(file);
-	/* first time the file will be tested, but not used */
-	if (tempStream->init()) {
-		_firstStream = tempStream;
-		_file = file;
-	} else
-		delete tempStream;
+FlacTrackInfo::FlacTrackInfo(const char *filename) :
+	_filename(filename),
+	_errorFlag(false) {
+	
+	// Try to open the file
+	Common::File file;
+	if (!file.open(_filename)) {
+		_errorFlag = true;
+		return;
+	}
+	
+	// Next, try to create a FlacInputStream from it
+	FlacInputStream *tempStream = new FlacInputStream(&file);
+
+	// If initialising the stream fails, we set the error flag
+	if (!tempStream || !tempStream->init())
+		_errorFlag = true;
+
+	delete tempStream;
 }
 
 void FlacTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
+	assert(!_errorFlag);
+
 	if (error()) {
 		debug(1, "FlacTrackInfo::play:  invalid state, method should not been called");
 	}
 
-	FlacInputStream *flac;
-
-	if (_firstStream != NULL) {
-		flac = _firstStream;
-		_firstStream = NULL;
-	} else {
-		flac = new FlacInputStream(_file);
-		flac->init();
+	// Open the file
+	Common::File *file = new Common::File();
+	if (!file || !file->open(_filename)) {
+		warning("FlacTrackInfo::play: failed to open '%s'", _filename.c_str());
+		delete file;
+		return;
 	}
 
+	// Create an AudioStream from the file
+	FlacInputStream *flac = new FlacInputStream(file);
+	flac->init();
+	file->decRef();
+
+	// Seek to the correct start position and start playback
 	if (flac->isStreamDecoderReady()) {
 		const FLAC__StreamMetadata_StreamInfo &info = flac->getStreamInfo();
 		if (duration)
@@ -921,38 +937,30 @@
 			return;
 		}
 		// startSample is beyond the existing Samples
-		debug(1, "FlacTrackInfo: Audiostream %s could not seek to frame %d (ca %d secs)", _file->name(), startFrame, startFrame/75);
+		debug(1, "FlacTrackInfo: Audiostream %s could not seek to frame %d (ca %d secs)", _filename.c_str(), startFrame, startFrame/75);
 		flac->finish();
 	}
 	delete flac;
 }
 
-FlacTrackInfo::~FlacTrackInfo() {
-	delete _firstStream;
-	delete _file;
-}
-
 DigitalTrackInfo* getFlacTrack(int track) {
 	assert(track >= 1);
 	char trackName[4][32];
-	File *file = new File();
 
 	sprintf(trackName[0], "track%d.flac", track);
 	sprintf(trackName[1], "track%02d.flac", track);
 	sprintf(trackName[2], "track%d.fla", track);
 	sprintf(trackName[3], "track%02d.fla", track);
 
-
 	for (int i = 0; i < 4; ++i) {
-		if (file->open(trackName[i])) {
-			FlacTrackInfo *trackInfo = new FlacTrackInfo(file);
+		if (Common::File::exists(trackName[i])) {
+			FlacTrackInfo *trackInfo = new FlacTrackInfo(trackName[i]);
 			if (!trackInfo->error())
 				return trackInfo;
 			delete trackInfo;
 		}
 	}
 
-	delete file;
 	return NULL;
 }
 

Modified: scummvm/trunk/sound/mp3.cpp
===================================================================
--- scummvm/trunk/sound/mp3.cpp	2007-02-20 22:18:48 UTC (rev 25756)
+++ scummvm/trunk/sound/mp3.cpp	2007-02-20 23:40:46 UTC (rev 25757)
@@ -167,7 +167,7 @@
 				if (_stream.error == MAD_ERROR_BUFLEN) {
 					break; // Read more data
 				} else if (MAD_RECOVERABLE(_stream.error)) {
-					debug(1, "MP3InputStream: Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
+					debug(6, "MP3InputStream: Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
 					continue;
 				} else {
 					warning("MP3InputStream: Unrecoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
@@ -193,8 +193,10 @@
 				if (_stream.error == MAD_ERROR_BUFLEN) {
 					break; // Read more data
 				} else if (MAD_RECOVERABLE(_stream.error)) {
-					// FIXME: should we do anything here?
-					debug(1, "MP3InputStream: Recoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
+					// Note: we will occasionally see MAD_ERROR_BADDATAPTR errors here.
+					// These are normal and expected (caused by our frame skipping (i.e. "seeking")
+					// code above).
+					debug(6, "MP3InputStream: Recoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
 					continue;
 				} else {
 					warning("MP3InputStream: Unrecoverable error in mad_frame_decode (%s)", mad_stream_errorstr(&_stream));
@@ -351,27 +353,27 @@
 	_filename(filename),
 	_errorFlag(false) {
 
+	// Try to open the file
 	Common::File file;
-	
-	// Try to open the file
 	if (!file.open(_filename)) {
 		_errorFlag = true;
 		return;
 	}
 	
-	// Next, try to create a MP3InputStream from it
+	// Next, try to create an MP3InputStream from it
+	MP3InputStream *tempStream = new MP3InputStream(&file, false);
 	
-	MP3InputStream *mp3Stream = new MP3InputStream(&file, false);
-	
 	// If we see EOS here then that means that not (enough) valid input
 	// data was given.
-	_errorFlag = mp3Stream->endOfData();
+	_errorFlag = tempStream->endOfData();
 	
 	// Clean up again	
-	delete mp3Stream;
+	delete tempStream;
 }
 
 void MP3TrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
+	assert(!_errorFlag);
+
 	mad_timer_t start;
 	mad_timer_t end;
 	
@@ -389,12 +391,14 @@
 	Common::File *file = new Common::File();
 	if (!file || !file->open(_filename)) {
 		warning("MP3TrackInfo::play: failed to open '%s'", _filename.c_str());
+		delete file;
 		return;
 	}
 
-	// Play it
+	// ... create an AudioStream ...
 	MP3InputStream *input = new MP3InputStream(file, true, start, end);
 	
+	// ... and play it
 	mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input);
 }
 

Modified: scummvm/trunk/sound/vorbis.cpp
===================================================================
--- scummvm/trunk/sound/vorbis.cpp	2007-02-20 22:18:48 UTC (rev 25756)
+++ scummvm/trunk/sound/vorbis.cpp	2007-02-20 23:40:46 UTC (rev 25757)
@@ -46,8 +46,6 @@
 
 namespace Audio {
 
-static AudioStream *makeVorbisStream(OggVorbis_File *file, int duration);
-
 // These are wrapper functions to allow using a File object to
 // provide data to the OggVorbis_File object.
 
@@ -129,8 +127,9 @@
 static int close_wrap(void *datasource) {
 	file_info *f = (file_info *) datasource;
 
-	f->file->decRef();
+	delete f->file;
 	delete f;
+
 	return 0;
 }
 
@@ -146,123 +145,6 @@
 
 
 #pragma mark -
-#pragma mark --- Ogg Vorbis Audio CD emulation ---
-#pragma mark -
-
-class VorbisTrackInfo : public DigitalTrackInfo {
-private:
-	File *_file;
-	OggVorbis_File _ov_file;
-	bool _error_flag;
-
-public:
-	VorbisTrackInfo(File *file);
-	~VorbisTrackInfo();
-	bool openTrack();
-	bool error() { return _error_flag; }
-	void play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration);
-};
-
-
-VorbisTrackInfo::VorbisTrackInfo(File *file) {
-//debug(5, "" __FILE__ ":%i", __LINE__);
-
-	_file = file;
-	if (openTrack()) {
-		warning("Invalid file format");
-		_error_flag = true;
-		_file = 0;
-	} else {
-		_error_flag = false;
-		_file->incRef();
-		ov_clear(&_ov_file);
-	}
-}
-
-bool VorbisTrackInfo::openTrack() {
-//debug(5, "" __FILE__ ":%i", __LINE__);
-	assert(_file);
-
-	file_info *f = new file_info;
-
-#if defined(__SYMBIAN32__)
-	// Symbian can't share filehandles between different threads.
-	// So create a new file  and seek that to the other filehandles position
-	f->file = new File;
-	f->file->open(_file->name());
-	f->file->seek(_file->pos());
-#else
-	f->file = _file;
-#endif
-
-	f->start = 0;
-	f->len = _file->size();
-	f->curr_pos = 0;
-	_file->seek(0);
-
-	bool err = (ov_open_callbacks((void *) f, &_ov_file, NULL, 0, g_File_wrap) < 0);
-	if (err) {
-#ifdef __SYMBIAN32__
-		delete f->file;
-#endif
-		delete f;
-	} else {
-#ifndef __SYMBIAN32__
-		_file->incRef();
-#endif	
-	}
-
-	return err;
-}
-
-VorbisTrackInfo::~VorbisTrackInfo() {
-//debug(5, "" __FILE__ ":%i", __LINE__);
-	if (! _error_flag) {
-		ov_clear(&_ov_file);
-		_file->decRef();
-	}
-}
-
-void VorbisTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
-//debug(5, "" __FILE__ ":%i", __LINE__);
-	bool err = openTrack(); err=err;//satisfy unused variable
-	assert(!err);
-
-#ifdef USE_TREMOR // In Tremor, the ov_time_seek() and ov_time_seek_page() calls take seeking positions in milliseconds as 64 bit integers, rather than in seconds as doubles as in Vorbisfile.
-#if defined(__SYMBIAN32__) && defined(__GCC32__) // SumthinWicked says: fixing "relocation truncated to fit: ARM_26 __fixdfdi" during linking on GCC, see portdefs.h
-	ov_time_seek(&_ov_file, (ogg_int64_t)scumm_fixdfdi(startFrame / 75.0 * 1000));
-#else
-	ov_time_seek(&_ov_file, (ogg_int64_t)(startFrame / 75.0 * 1000));
-#endif
-#else
-	ov_time_seek(&_ov_file, startFrame / 75.0);
-#endif
-
-	AudioStream *input = makeVorbisStream(&_ov_file, duration * ov_info(&_ov_file, -1)->rate / 75);
-	mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input);
-}
-
-DigitalTrackInfo *getVorbisTrack(int track) {
-	char trackName[2][32];
-	File *file = new File();
-
-	sprintf(trackName[0], "track%d.ogg", track);
-	sprintf(trackName[1], "track%02d.ogg", track);
-
-	for (int i = 0; i < 2; ++i) {
-		if (file->open(trackName[i])) {
-			VorbisTrackInfo *trackInfo = new VorbisTrackInfo(file);
-			file->decRef();
-			if (!trackInfo->error())
-				return trackInfo;
-			delete trackInfo;
-		}
-	}
-	delete file;
-	return NULL;
-}
-
-#pragma mark -
 #pragma mark --- Ogg Vorbis stream ---
 #pragma mark -
 
@@ -376,11 +258,6 @@
 	_bufferEnd = (int16 *)read_pos;
 }
 
-static AudioStream *makeVorbisStream(OggVorbis_File *file, int duration) {
-//debug(5, "" __FILE__ ":%i", __LINE__);
-	return new VorbisInputStream(file, duration, false);
-}
-
 AudioStream *makeVorbisStream(File *file, uint32 size) {
 //debug(5, "" __FILE__ ":%i", __LINE__);
 	OggVorbis_File *ov_file = new OggVorbis_File;
@@ -413,6 +290,102 @@
 }
 
 
+#pragma mark -
+#pragma mark --- Ogg Vorbis Audio CD emulation ---
+#pragma mark -
+
+class VorbisTrackInfo : public DigitalTrackInfo {
+private:
+	Common::String _filename;
+	bool _errorFlag;
+
+public:
+	VorbisTrackInfo(const char *filename);
+	bool openTrack(OggVorbis_File *ovFile);
+	bool error() { return _errorFlag; }
+	void play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration);
+};
+
+
+VorbisTrackInfo::VorbisTrackInfo(const char *filename) :
+	_filename(filename),
+	_errorFlag(false) {
+
+	OggVorbis_File ov_file;
+	_errorFlag = openTrack(&ov_file);
+	
+	if (!_errorFlag)
+		ov_clear(&ov_file);
+}
+
+bool VorbisTrackInfo::openTrack(OggVorbis_File *ovFile) {
+	bool err;
+
+	file_info *f = new file_info;
+	assert(f);
+	f->file = new File;
+	assert(f->file);
+
+	err = !f->file->open(_filename);
+	
+	if (!err) {
+		f->start = 0;
+		f->len = f->file->size();
+		f->curr_pos = 0;
+	
+		err = (ov_open_callbacks((void *) f, ovFile, NULL, 0, g_File_wrap) < 0);
+	}
+
+	if (err) {
+		delete f->file;
+		delete f;
+	}
+
+	return err;
+}
+
+void VorbisTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
+	OggVorbis_File *ovFile = new OggVorbis_File;
+	bool err = openTrack(ovFile);
+	assert(!err);
+
+#ifdef USE_TREMOR
+	// In Tremor, the ov_time_seek() and ov_time_seek_page() calls take seeking
+	// positions in milliseconds as 64 bit integers, rather than in seconds as
+	// doubles as in Vorbisfile.
+#if defined(__SYMBIAN32__) && defined(__GCC32__)
+	// SumthinWicked says: fixing "relocation truncated to fit: ARM_26 __fixdfdi" during linking on GCC, see portdefs.h
+	ov_time_seek(ovFile, (ogg_int64_t)scumm_fixdfdi(startFrame / 75.0 * 1000));
+#else
+	ov_time_seek(ovFile, (ogg_int64_t)(startFrame / 75.0 * 1000));
+#endif
+#else
+	ov_time_seek(ovFile, startFrame / 75.0);
+#endif
+
+	AudioStream *input =  new VorbisInputStream(ovFile, duration * ov_info(ovFile, -1)->rate / 75, true);
+	mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input);
+}
+
+DigitalTrackInfo *getVorbisTrack(int track) {
+	char trackName[2][32];
+
+	sprintf(trackName[0], "track%d.ogg", track);
+	sprintf(trackName[1], "track%02d.ogg", track);
+
+	for (int i = 0; i < 2; ++i) {
+		if (Common::File::exists(trackName[i])) {
+			VorbisTrackInfo *trackInfo = new VorbisTrackInfo(trackName[i]);
+			if (!trackInfo->error())
+				return trackInfo;
+			delete trackInfo;
+		}
+	}
+	return NULL;
+}
+
+
+
 } // End of namespace Audio
 
 #endif // #ifdef USE_VORBIS


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list