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

Bluddy at users.sourceforge.net Bluddy at users.sourceforge.net
Sun May 30 11:47:01 CEST 2010


Revision: 49319
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49319&view=rev
Author:   Bluddy
Date:     2010-05-30 09:47:00 +0000 (Sun, 30 May 2010)

Log Message:
-----------
PSP: added preliminary support for using ME hardware to play MP3 files. If the decoder fails to load, MAD is used instead. Disable with DISABLE_PSP_MP3.

Modified Paths:
--------------
    scummvm/trunk/backends/platform/psp/Makefile
    scummvm/trunk/backends/platform/psp/module.mk
    scummvm/trunk/backends/platform/psp/psp.spec
    scummvm/trunk/sound/decoders/mp3.cpp

Added Paths:
-----------
    scummvm/trunk/backends/platform/psp/mp3.cpp
    scummvm/trunk/backends/platform/psp/mp3.h

Modified: scummvm/trunk/backends/platform/psp/Makefile
===================================================================
--- scummvm/trunk/backends/platform/psp/Makefile	2010-05-29 23:56:37 UTC (rev 49318)
+++ scummvm/trunk/backends/platform/psp/Makefile	2010-05-30 09:47:00 UTC (rev 49319)
@@ -129,7 +129,8 @@
 SDLLIBS  := $(shell $(PSPBIN)/sdl-config --libs)
 # PSP LIBS
 PSPLIBS =  -lpspprof -lpspvfpu -lpspdebug -lpspgu -lpspge -lpspdisplay -lpspctrl -lpspsdk \
-	-lpsputility -lpspuser -lpsppower -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lpspkernel
+	-lpsputility -lpspuser -lpsppower -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lpspaudiocodec \
+	-lpspkernel
 
 # Add in PSPSDK includes and libraries.
 CXXFLAGS += $(SDLFLAGS)
@@ -149,7 +150,8 @@
 	psploader.o \
 	pspkeyboard.o \
 	audio.o \
-	thread.o
+	thread.o \
+	mp3.o
 
 # Include common Scummvm makefile
 include $(srcdir)/Makefile.common

Modified: scummvm/trunk/backends/platform/psp/module.mk
===================================================================
--- scummvm/trunk/backends/platform/psp/module.mk	2010-05-29 23:56:37 UTC (rev 49318)
+++ scummvm/trunk/backends/platform/psp/module.mk	2010-05-30 09:47:00 UTC (rev 49319)
@@ -14,7 +14,8 @@
 	psploader.o \
 	pspkeyboard.o \
 	audio.o \
-	thread.o
+	thread.o \
+	mp3.o
 
 MODULE_DIRS += \
 	backends/platform/psp/

Added: scummvm/trunk/backends/platform/psp/mp3.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/mp3.cpp	                        (rev 0)
+++ scummvm/trunk/backends/platform/psp/mp3.cpp	2010-05-30 09:47:00 UTC (rev 49319)
@@ -0,0 +1,487 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+
+#include "common/debug.h"
+#include "common/stream.h"
+#include "common/util.h"
+#include "common/singleton.h"
+#include "common/mutex.h"
+
+#include "sound/audiostream.h"
+
+#include <pspaudiocodec.h>
+#include <psputility_modules.h>
+#include <pspthreadman.h>
+#include <pspsysmem.h>
+#include <pspmodulemgr.h>
+#include <psputility_avmodules.h>
+#include <mad.h> 
+#include "backends/platform/psp/mp3.h"
+
+//#define DISABLE_PSP_MP3		// to make us use the regular MAD decoder instead
+
+//#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
+//#define __PSP_DEBUG_PRINT__ 
+#include "backends/platform/psp/trace.h"
+
+//#define PRINT_BUFFERS	/* to debug MP3 buffers */
+
+namespace Audio {
+
+class Mp3PspStream;
+
+bool Mp3PspStream::_decoderInit = false;	// has the decoder been initialized
+#ifdef DISABLE_PSP_MP3
+bool Mp3PspStream::_decoderFail = true;		// pretend the decoder failed
+#else
+bool Mp3PspStream::_decoderFail = false;	// has the decoder failed to load
+#endif
+
+bool Mp3PspStream::initDecoder() {
+	DEBUG_ENTER_FUNC();
+	
+	if (_decoderInit) {
+		PSP_ERROR("Already initialized!");
+		return true;
+	}
+
+	// Based on PSP firmware version, we need to do different things to do Media Engine processing
+	uint32 firmware = sceKernelDevkitVersion();
+	PSP_DEBUG_PRINT("Firmware version 0x%x\n", firmware);
+    if (firmware == 0x01050001){
+		if (!loadStartAudioModule((char *)(void *)"flash0:/kd/me_for_vsh.prx",
+			PSP_MEMORY_PARTITION_KERNEL)) {
+			PSP_ERROR("failed to load me_for_vsh.prx. ME cannot start.\n");
+			_decoderFail = true;
+			return false;
+		}
+        if (!loadStartAudioModule((char *)(void *)"flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL)) {
+			PSP_ERROR("failed to load audiocodec.prx. ME cannot start.\n");
+			_decoderFail = true;
+			return false;
+		}	
+    } else {		
+        if (sceUtilityLoadAvModule(PSP_AV_MODULE_AVCODEC) < 0) {
+			PSP_ERROR("failed to load AVCODEC module.\n");
+			_decoderFail = true;
+			return false;
+		}
+	}
+	
+	PSP_INFO_PRINT("Using PSP's ME for MP3\n");	// important to know this is happening
+
+	_decoderInit = true;
+	return true;
+}
+
+bool Mp3PspStream::stopDecoder() {
+	DEBUG_ENTER_FUNC();
+	
+	if (!_decoderInit)
+		return true;
+		
+	// Based on PSP firmware version, we need to do different things to do Media Engine processing
+    if (sceKernelDevkitVersion() == 0x01050001){
+/*      if (!unloadAudioModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL) ||
+			!unloadAudioModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL) {
+			PSP_ERROR("failed to unload audio module\n");
+			return false;
+		}
+*/
+    }else{
+        if (sceUtilityUnloadModule(PSP_MODULE_AV_AVCODEC) < 0) {
+			PSP_ERROR("failed to unload avcodec module\n");
+			return false;
+		}	
+	}
+		
+	_decoderInit = false;	
+	return true;
+}
+
+//Load a PSP audio module
+bool Mp3PspStream::loadStartAudioModule(const char *modname, int partition){
+	DEBUG_ENTER_FUNC();
+
+    SceKernelLMOption option;
+    SceUID modid;
+
+    memset(&option, 0, sizeof(option));
+    option.size = sizeof(option);
+    option.mpidtext = partition;
+    option.mpiddata = partition;
+    option.position = 0;
+    option.access = 1;
+
+    modid = sceKernelLoadModule(modname, 0, &option);
+    if (modid < 0) {
+		PSP_ERROR("Failed to load module %s. Got error 0x%x\n", modname, modid);
+        return false;
+	}
+
+    int ret = sceKernelStartModule(modid, 0, NULL, NULL, NULL);
+	if (ret < 0) {
+		PSP_ERROR("Failed to start module %s. Got error 0x%x\n", modname, ret);
+        return false;
+	}
+	return true;
+}
+
+// TODO: make parallel function for unloading the 1.50 modules
+
+Mp3PspStream::Mp3PspStream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose) :
+	_inStream(inStream),
+	_disposeAfterUse(dispose),
+	_pcmLength(0),
+	_posInFrame(0),
+	_state(MP3_STATE_INIT),
+	_length(0, 1000),
+	_sampleRate(0),
+	_totalTime(mad_timer_zero) {
+	
+	DEBUG_ENTER_FUNC();
+
+	assert(_decoderInit);	// must be initialized by now
+	
+	// let's leave the buffer guard -- who knows, it may be good?
+	memset(_buf, 0, sizeof(_buf));
+	memset(_codecInBuffer, 0, sizeof(_codecInBuffer));
+	
+	initStream();	// init needed stuff for the stream
+
+	while (_state != MP3_STATE_EOS)
+		findValidHeader();	// get a first header so we can read basic stuff
+	
+	_sampleRate = _header.samplerate;	// copy it before it gets destroyed
+	
+	_length = Timestamp(mad_timer_count(_totalTime, MAD_UNITS_MILLISECONDS), getRate());
+	
+	//initStreamME();		// init the stuff needed for the ME to work
+	
+	deinitStream();
+	//releaseStreamME();
+
+	_state = MP3_STATE_INIT;
+}
+
+int Mp3PspStream::initStream() {
+	DEBUG_ENTER_FUNC();
+
+	if (_state != MP3_STATE_INIT)
+		deinitStream();
+
+	// Init MAD
+	mad_stream_init(&_stream);
+	mad_header_init(&_header);
+
+	// Reset the stream data
+	_inStream->seek(0, SEEK_SET);
+	_totalTime = mad_timer_zero;
+	_posInFrame = 0;
+
+	// Update state
+	_state = MP3_STATE_READY;
+
+	// Read the first few sample bytes into the buffer
+	readMP3DataIntoBuffer();
+	
+	return true;
+}
+
+bool Mp3PspStream::initStreamME() {
+	// The following will eventually go into the thread
+	sceAudiocodecReleaseEDRAM(_codecParams);	// do we need this?
+
+	memset(_codecParams, 0, sizeof(_codecParams));
+	
+	// Init the MP3 hardware
+	int ret = 0;
+	ret = sceAudiocodecCheckNeedMem(_codecParams, 0x1002);
+	if (ret < 0) {
+		PSP_ERROR("failed to init MP3 ME module. sceAudiocodecCheckNeedMem returned 0x%x.\n", ret);
+		return false;
+	}
+	PSP_DEBUG_PRINT("sceAudiocodecCheckNeedMem returned %d\n", ret);
+	ret = sceAudiocodecGetEDRAM(_codecParams, 0x1002);
+	if (ret < 0) {
+		PSP_ERROR("failed to init MP3 ME module. sceAudiocodecGetEDRAM returned 0x%x.\n", ret);
+		return false;
+	}
+	PSP_DEBUG_PRINT("sceAudioCodecGetEDRAM returned %d\n", ret);
+	
+	PSP_DEBUG_PRINT("samplerate[%d]\n", _sampleRate);
+	_codecParams[10] = _sampleRate;
+	
+	ret = sceAudiocodecInit(_codecParams, 0x1002);
+	if (ret < 0) {
+		PSP_ERROR("failed to init MP3 ME module. sceAudiocodecInit returned 0x%x.\n", ret);
+		return false;
+	}
+	
+	return true;
+}
+
+Mp3PspStream::~Mp3PspStream() {
+	DEBUG_ENTER_FUNC();
+	
+	deinitStream();
+	releaseStreamME(); 	// free the memory used for this stream
+
+	if (_disposeAfterUse == DisposeAfterUse::YES)
+		delete _inStream;
+}
+
+void Mp3PspStream::deinitStream() {
+	DEBUG_ENTER_FUNC();
+
+	if (_state == MP3_STATE_INIT)
+		return;
+
+	// Deinit MAD
+	mad_header_finish(&_header);
+	mad_stream_finish(&_stream);
+	
+	_state = MP3_STATE_EOS;
+}
+
+void Mp3PspStream::releaseStreamME() {
+	sceAudiocodecReleaseEDRAM(_codecParams);
+}	
+
+void Mp3PspStream::decodeMP3Data() {
+	DEBUG_ENTER_FUNC();
+	
+	do {
+		if (_state == MP3_STATE_INIT) {
+			initStream();
+			initStreamME();
+		}
+
+		if (_state == MP3_STATE_EOS)
+			return;
+			
+		findValidHeader();	// seach for next valid header
+
+		while (_state == MP3_STATE_READY) {
+			_stream.error = MAD_ERROR_NONE;
+
+			uint32 frame_size = _stream.next_frame - _stream.this_frame;
+			uint32 samplesPerFrame = _header.layer == MAD_LAYER_III ? 576 : 1152; 	// Varies by layer
+			// calculate frame size -- try
+			//uint32 calc_frame_size = ((144 * _header.bitrate) / 22050) + (_header.flags & MAD_FLAG_PADDING ? 1 : 0);
+			
+			// Get stereo/mono
+			uint32 multFactor = 1;
+			if (_header.mode != MAD_MODE_SINGLE_CHANNEL)	// mono	- x2 for 16bit
+				multFactor *= 2;							// stereo - x4 for 16bit
+			
+			PSP_DEBUG_PRINT("MP3 frame size[%d]. Samples[%d]. Multfactor[%d] pad[%d]\n", frame_size, samplesPerFrame, multFactor, _header.flags & MAD_FLAG_PADDING);
+			memcpy(_codecInBuffer, _stream.this_frame, frame_size);	// we need it aligned
+
+			// set up parameters for ME
+			_codecParams[6] = (unsigned long)_codecInBuffer;
+			_codecParams[8] = (unsigned long)_pcmSamples;
+			_codecParams[7] = frame_size;
+			_codecParams[9] = samplesPerFrame * multFactor;	// x2 for stereo
+			
+			// debug
+#ifdef PRINT_BUFFERS
+			PSP_DEBUG_PRINT("mp3 frame:\n");
+			for (int i=0; i < (int)frame_size; i++) {
+				PSP_DEBUG_PRINT_SAMELN("%x ", _codecInBuffer[i]);
+			}
+			PSP_DEBUG_PRINT("\n");
+#endif
+			// Decode the next frame
+			// This function blocks. We'll want to put it in a thread
+			int ret = sceAudiocodecDecode(_codecParams, 0x1002);
+			if (ret < 0) {
+				PSP_ERROR("failed to decode MP3 data in ME. sceAudiocodecDecode returned 0x%x\n", ret);
+				// handle error here
+			}
+
+#ifdef PRINT_BUFFERS
+			PSP_DEBUG_PRINT("PCM frame:\n");
+			for (int i=0; i < (int)_codecParams[9]; i+=2) {	// changed from i+=2
+				PSP_DEBUG_PRINT_SAMELN("%d ", (int16)_pcmSamples[i]);
+			}
+			PSP_DEBUG_PRINT("\n");
+#endif
+			_pcmLength = samplesPerFrame;
+			_posInFrame = 0;
+			break;
+		}
+	} while (_state != MP3_STATE_EOS && _stream.error == MAD_ERROR_BUFLEN);
+
+	if (_stream.error != MAD_ERROR_NONE)	// catch EOS
+		_state = MP3_STATE_EOS;
+}
+
+void Mp3PspStream::readMP3DataIntoBuffer() {
+	DEBUG_ENTER_FUNC();
+
+	uint32 remaining = 0;
+
+	// Give up immediately if we already used up all data in the stream
+	if (_inStream->eos()) {
+		_state = MP3_STATE_EOS;
+		return;
+	}
+
+	if (_stream.next_frame) {
+		// If there is still data in the MAD stream, we need to preserve it.
+		// Note that we use memmove, as we are reusing the same buffer,
+		// and hence the data regions we copy from and to may overlap.
+		remaining = _stream.bufend - _stream.next_frame;
+		assert(remaining < BUFFER_SIZE);	// Paranoia check
+		memmove(_buf, _stream.next_frame, remaining);	// TODO: may want another buffer
+	}
+
+	// Try to read the next block
+	uint32 size = _inStream->read(_buf + remaining, BUFFER_SIZE - remaining);
+	if (size <= 0) {
+		_state = MP3_STATE_EOS;
+		return;
+	}
+
+	// Feed the data we just read into the stream decoder
+	_stream.error = MAD_ERROR_NONE;
+	mad_stream_buffer(&_stream, _buf, size + remaining);	// just setup the pointers
+}
+
+bool Mp3PspStream::seek(const Timestamp &where) {
+	DEBUG_ENTER_FUNC();
+
+	if (where == _length) {
+		_state = MP3_STATE_EOS;
+		return true;
+	} else if (where > _length) {
+		return false;
+	}
+
+	const uint32 time = where.msecs();
+
+	mad_timer_t destination;
+	mad_timer_set(&destination, time / 1000, time % 1000, 1000);
+
+	// Check if we need to rewind
+	if (_state != MP3_STATE_READY || mad_timer_compare(destination, _totalTime) < 0) {
+		initStream();
+		initStreamME();
+	}
+
+	// The ME will need clear data no matter what once we seek?
+	//if (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS)
+	//	initStreamME();
+
+	// Skip ahead
+	while (mad_timer_compare(destination, _totalTime) > 0 && _state != MP3_STATE_EOS)
+		findValidHeader();
+
+	return (_state != MP3_STATE_EOS);
+}
+
+// Seek in the stream, finding the next valid header
+void Mp3PspStream::findValidHeader() {
+	DEBUG_ENTER_FUNC();
+
+	if (_state != MP3_STATE_READY)
+		return;
+
+	// If necessary, load more data into the stream decoder
+	if (_stream.error == MAD_ERROR_BUFLEN)
+		readMP3DataIntoBuffer();
+
+	while (_state != MP3_STATE_EOS) {
+		_stream.error = MAD_ERROR_NONE;
+
+		// Decode the next header.
+		if (mad_header_decode(&_header, &_stream) == -1) {
+			if (_stream.error == MAD_ERROR_BUFLEN) {
+				readMP3DataIntoBuffer();  // Read more data
+				continue;
+			} else if (MAD_RECOVERABLE(_stream.error)) {
+				debug(6, "MP3PSPStream: Recoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
+				continue;
+			} else {
+				warning("MP3PSPStream: Unrecoverable error in mad_header_decode (%s)", mad_stream_errorstr(&_stream));
+				break;
+			}
+		}
+
+		// Sum up the total playback time so far
+		mad_timer_add(&_totalTime, _header.duration);
+		break;
+	}
+
+	if (_stream.error != MAD_ERROR_NONE)
+		_state = MP3_STATE_EOS;
+}
+
+int Mp3PspStream::readBuffer(int16 *buffer, const int numSamples) {
+	DEBUG_ENTER_FUNC();
+
+	int samples = 0;
+#ifdef PRINT_BUFFERS	
+	int16 *debugBuffer = buffer;
+#endif	
+	
+	// Keep going as long as we have input available
+	while (samples < numSamples && _state != MP3_STATE_EOS) {
+		const int len = MIN(numSamples, samples + (int)(_pcmLength - _posInFrame) * MAD_NCHANNELS(&_header));
+		
+		while (samples < len) {
+			*buffer++ = _pcmSamples[_posInFrame << 1];
+			samples++;
+			if (MAD_NCHANNELS(&_header) == 2) {
+				*buffer++ = _pcmSamples[(_posInFrame << 1) + 1];
+				samples++;
+			} 
+			_posInFrame++;	// always skip an extra sample since ME always outputs stereo
+		}
+		
+		//memcpy(buffer, &_pcmSamples[_posInFrame], len << 1);	   // 16 bits
+		//_posInFrame += len;		// next time we start from the middle
+
+		if (_posInFrame >= _pcmLength) {
+			// We used up all PCM data in the current frame -- read & decode more
+			decodeMP3Data();
+		}
+	}
+	
+#ifdef PRINT_BUFFERS
+		PSP_INFO_PRINT("buffer:\n");
+		for (int i = 0; i<numSamples; i++)
+			PSP_INFO_PRINT("%d ", debugBuffer[i]);
+		PSP_INFO_PRINT("\n\n");
+#endif		
+	
+	return samples;
+}
+
+} // End of namespace Audio
+
+


Property changes on: scummvm/trunk/backends/platform/psp/mp3.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/platform/psp/mp3.h
===================================================================
--- scummvm/trunk/backends/platform/psp/mp3.h	                        (rev 0)
+++ scummvm/trunk/backends/platform/psp/mp3.h	2010-05-30 09:47:00 UTC (rev 49319)
@@ -0,0 +1,121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SOUND_MP3_PSP_H
+#define SOUND_MP3_PSP_H
+
+#include "common/types.h"
+#include "common/scummsys.h"
+
+namespace Common {
+	class SeekableReadStream;
+}
+
+namespace Audio {
+
+class AudioStream;
+class SeekableAudioStream;
+
+class Mp3PspStream : public SeekableAudioStream {
+protected:
+	enum State {
+		MP3_STATE_INIT,		// Need to init the decoder
+		MP3_STATE_READY,	// ready for processing data
+		MP3_STATE_EOS		// end of data reached (may need to loop)
+	};
+
+	#define MAX_SAMPLES_PER_FRAME	2048 * 2
+	int16 _pcmSamples[MAX_SAMPLES_PER_FRAME] __attribute__((aligned(64)));	// samples to output PCM data into
+	byte _codecInBuffer[3072] __attribute__((aligned(64))); // the codec always needs alignment
+	unsigned long _codecParams[65]__attribute__((aligned(64)));		// TODO: change to struct
+
+	Common::SeekableReadStream *_inStream;
+	DisposeAfterUse::Flag _disposeAfterUse;
+	
+	uint32 _pcmLength;		// how many pcm samples we have (/2 for mono)
+	
+	uint _posInFrame;		// position in frame
+	State _state;			// what state the stream is in
+
+	Timestamp _length;
+	uint32 _sampleRate;
+
+	mad_timer_t _totalTime;
+	mad_stream _stream;		//
+	mad_header _header;		// This is all we need from libmad
+	
+	static bool _decoderInit;	// has the decoder been initialized
+	static bool _decoderFail;	// has the decoder failed to load
+	
+	enum {
+		BUFFER_SIZE = 5 * 8192
+	};
+
+	// This buffer contains a slab of input data
+	byte _buf[BUFFER_SIZE + MAD_BUFFER_GUARD];
+	
+	void decodeMP3Data();
+	void readMP3DataIntoBuffer();
+
+	static bool loadStartAudioModule(const char *modname, int partition);
+	int initStream();
+	void findValidHeader();
+	void deinitStream();
+
+	// to init and uninit ME decoder
+	static bool initDecoder();
+	static bool stopDecoder();
+	
+	// ME functions for stream
+	bool initStreamME();
+	void releaseStreamME();
+	
+public:
+	Mp3PspStream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose);
+	~Mp3PspStream();
+	
+	// This function avoids having to create streams when it's not possible
+	static inline bool isOkToCreateStream() {
+		if (_decoderFail)			// fatal failure
+			return false;
+		if (!_decoderInit)			// if we're not initialized
+			if (!initDecoder())		// check if we failed init
+				return false;
+		return true;	
+	}
+
+	int readBuffer(int16 *buffer, const int numSamples);
+
+	bool endOfData() const		{ return _state == MP3_STATE_EOS; }
+	bool isStereo() const		{ return MAD_NCHANNELS(&_header) == 2; }
+	int getRate() const			{ return _header.samplerate; }
+
+	bool seek(const Timestamp &where);
+	Timestamp getLength() const { return _length; }
+};
+
+} // End of namespace Audio
+
+#endif // #ifndef SOUND_MP3_PSP_H


Property changes on: scummvm/trunk/backends/platform/psp/mp3.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Modified: scummvm/trunk/backends/platform/psp/psp.spec
===================================================================
--- scummvm/trunk/backends/platform/psp/psp.spec	2010-05-29 23:56:37 UTC (rev 49318)
+++ scummvm/trunk/backends/platform/psp/psp.spec	2010-05-30 09:47:00 UTC (rev 49319)
@@ -1,3 +1,3 @@
 %rename lib	old_lib
 *lib:
-%(old_lib) -lz -lstdc++ -lc -lm -lpspprof -lpspvfpu -lpspdebug -lpspgu -lpspge -lpspdisplay -lpspctrl -lpspsdk -lpsputility -lpspuser -lpsppower -lpsphprm  -lpsprtc -lpspaudio -lpspkernel
+%(old_lib) -lz -lstdc++ -lc -lm -lpspprof -lpspvfpu -lpspdebug -lpspgu -lpspge -lpspdisplay -lpspctrl -lpspsdk -lpsputility -lpspuser -lpsppower -lpsphprm  -lpsprtc -lpspaudio -lpspaudiocodec -lpspkernel

Modified: scummvm/trunk/sound/decoders/mp3.cpp
===================================================================
--- scummvm/trunk/sound/decoders/mp3.cpp	2010-05-29 23:56:37 UTC (rev 49318)
+++ scummvm/trunk/sound/decoders/mp3.cpp	2010-05-30 09:47:00 UTC (rev 49319)
@@ -36,7 +36,9 @@
 
 #include <mad.h>
 
-
+#if defined(__PSP__)
+	#include "backends/platform/psp/mp3.h"
+#endif
 namespace Audio {
 
 
@@ -347,7 +349,18 @@
 SeekableAudioStream *makeMP3Stream(
 	Common::SeekableReadStream *stream,
 	DisposeAfterUse::Flag disposeAfterUse) {
+	
+#if defined(__PSP__)
+	SeekableAudioStream *s = 0;
+	
+	if (Mp3PspStream::isOkToCreateStream())
+		s = new Mp3PspStream(stream, disposeAfterUse);
+		
+	if (!s)	// go to regular MAD mp3 stream if ME fails
+		s = new MP3Stream(stream, disposeAfterUse);
+#else
 	SeekableAudioStream *s = new MP3Stream(stream, disposeAfterUse);
+#endif
 	if (s && s->endOfData()) {
 		delete s;
 		return 0;


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