[Scummvm-cvs-logs] SF.net SVN: scummvm:[52191] scummvm/trunk/backends/platform/psp

bluddy at users.sourceforge.net bluddy at users.sourceforge.net
Wed Aug 18 18:58:33 CEST 2010


Revision: 52191
          http://scummvm.svn.sourceforge.net/scummvm/?rev=52191&view=rev
Author:   bluddy
Date:     2010-08-18 16:58:32 +0000 (Wed, 18 Aug 2010)

Log Message:
-----------
PSP: fixed issue in ME MP3 player that prevented different MP3 layers and versions from working.

MAD doesn't give enough information to decide the length of the PCM data -- it provides the Layer but not the MPEG version. I had to read the MP3 header directly to figure it out. This fixes issues with any MP3 files that might be used in any of the games.

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

Modified: scummvm/trunk/backends/platform/psp/mp3.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/mp3.cpp	2010-08-18 16:44:12 UTC (rev 52190)
+++ scummvm/trunk/backends/platform/psp/mp3.cpp	2010-08-18 16:58:32 UTC (rev 52191)
@@ -60,6 +60,21 @@
 bool Mp3PspStream::_decoderFail = false;	// has the decoder failed to load
 #endif
 
+// Arranged in groups of 3 (layers), starting with MPEG-1 and ending with MPEG 2.5
+static uint32 mp3SamplesPerFrame[9] = {384, 1152, 1152, 384, 1152, 576, 384, 1152, 576};
+
+// The numbering below doesn't correspond to the way they are in the header
+enum {
+	MPEG_VER1 = 0,
+	MPEG_VER1_HEADER = 0x3,
+	MPEG_VER2 = 1,
+	MPEG_VER2_HEADER = 0x2,
+	MPEG_VER2_5 = 2,
+	MPEG_VER2_5_HEADER = 0x0
+};
+
+#define HEADER_GET_MPEG_VERSION(x) ((((x)[1])>>3) & 0x3)
+
 bool Mp3PspStream::initDecoder() {
 	DEBUG_ENTER_FUNC();
 	
@@ -104,7 +119,7 @@
 		return true;
 		
 	// Based on PSP firmware version, we need to do different things to do Media Engine processing
-    if (sceKernelDevkitVersion() == 0x01050001){
+    if (sceKernelDevkitVersion() == 0x01050001){  // TODO: how do we unload?
 /*      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");
@@ -172,17 +187,16 @@
 	
 	initStream();	// init needed stuff for the stream
 
+	findValidHeader();	// get a first header so we can read basic stuff
+	
+	_sampleRate = _header.samplerate;	// copy it before it gets destroyed
+		
 	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;
 }
@@ -284,27 +298,23 @@
 			
 		findValidHeader();	// seach for next valid header
 
-		while (_state == MP3_STATE_READY) {
+		while (_state == MP3_STATE_READY) {	// not a real 'while'. Just for easy flow
 			_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);
+			updatePcmLength(); // Retrieve the number of PCM samples. 
+							   // We seem to change this, so it needs to be dynamic
+						
+			PSP_DEBUG_PRINT("MP3 frame size[%d]. pcmLength[%d]\n", frame_size, _pcmLength);
+
 			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
+			_codecParams[9] = _pcmLength * 2;	// x2 for stereo, though this one's not so important
 			
 			// debug
 #ifdef PRINT_BUFFERS
@@ -319,7 +329,6 @@
 			int ret = sceAudiocodecDecode(_codecParams, 0x1002);
 			if (ret < 0) {
 				PSP_INFO_PRINT("failed to decode MP3 data in ME. sceAudiocodecDecode returned 0x%x\n", ret);
-				// handle error here
 			}
 
 #ifdef PRINT_BUFFERS
@@ -329,7 +338,6 @@
 			}
 			PSP_DEBUG_PRINT("\n");
 #endif
-			_pcmLength = samplesPerFrame;
 			_posInFrame = 0;
 			break;
 		}
@@ -339,6 +347,27 @@
 		_state = MP3_STATE_EOS;
 }
 
+inline void Mp3PspStream::updatePcmLength() {
+	uint32 mpegVer = HEADER_GET_MPEG_VERSION(_stream.this_frame);	// sadly, MAD can't do this for us
+	PSP_DEBUG_PRINT("mpeg ver[%x]\n", mpegVer);
+	switch (mpegVer) {
+		case MPEG_VER1_HEADER:
+			mpegVer = MPEG_VER1;
+			break;
+		case MPEG_VER2_HEADER:
+			mpegVer = MPEG_VER2;
+			break;
+		case MPEG_VER2_5_HEADER:
+			mpegVer = MPEG_VER2_5;
+			break;
+		default:
+			PSP_ERROR("Unknown MPEG version %x\n", mpegVer);
+			break;
+	}
+	PSP_DEBUG_PRINT("layer[%d]\n", _header.layer);
+	_pcmLength = mp3SamplesPerFrame[(mpegVer * 3) + _header.layer - 1];
+}
+
 void Mp3PspStream::readMP3DataIntoBuffer() {
 	DEBUG_ENTER_FUNC();
 
@@ -392,10 +421,6 @@
 		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();
@@ -462,9 +487,6 @@
 			_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();
@@ -481,6 +503,4 @@
 	return samples;
 }
 
-} // End of namespace Audio
-
-
+} // End of namespace Audio
\ No newline at end of file

Modified: scummvm/trunk/backends/platform/psp/mp3.h
===================================================================
--- scummvm/trunk/backends/platform/psp/mp3.h	2010-08-18 16:44:12 UTC (rev 52190)
+++ scummvm/trunk/backends/platform/psp/mp3.h	2010-08-18 16:58:32 UTC (rev 52191)
@@ -46,7 +46,7 @@
 		MP3_STATE_EOS		// end of data reached (may need to loop)
 	};
 
-	#define MAX_SAMPLES_PER_FRAME	2048 * 2
+	#define MAX_SAMPLES_PER_FRAME	1152 * 2	/* x2 for stereo */
 	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
@@ -54,7 +54,7 @@
 	Common::SeekableReadStream *_inStream;
 	DisposeAfterUse::Flag _disposeAfterUse;
 	
-	uint32 _pcmLength;		// how many pcm samples we have (/2 for mono)
+	uint32 _pcmLength;		// how many pcm samples we have for this type of file (x2 this for stereo)
 	
 	uint _posInFrame;		// position in frame
 	State _state;			// what state the stream is in
@@ -83,7 +83,8 @@
 	int initStream();
 	void findValidHeader();
 	void deinitStream();
-
+	void updatePcmLength();
+	
 	// to init and uninit ME decoder
 	static bool initDecoder();
 	static bool stopDecoder();


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