MP3 and OGG support on Python for PSP

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

MP3 and OGG support on Python for PSP

Post by carlosedp »

I have added support for MP3 and OGG playback inside my current Stackless Python port.

I still need to clean up and document the functions. Its based on libtremor and libmad that are available from the SVN.

The API will be more or less the same... like:

Code: Select all

import pspogg, psp2d

pspmp3.init(channel)
pspmp3.load('file.mp3')
pspmp3.play()

while 1:
    pad = psp2d.Controller()
    if pspmp3.endofstream() == 1 or pad.cross:
        pspmp3.end()
        break

print "End"
What do you guys think, it will have a function to return the current music time too...

Tomorrow I will post more details on my site: http://themindcaster.blogspot.com

Carlos
sakya
Posts: 190
Joined: Fri Apr 28, 2006 5:48 pm
Contact:

Re: MP3 and OGG support on Python for PSP

Post by sakya »

Ciao! :)
carlosedp wrote:I have added support for MP3 and OGG playback inside my current Stackless Python port.
Wow, very good work. :)
I also tried (without C knowledge) to add mp3 playback some month ago, but failed. ;)
If you used the mp3player.c file be aware that this loads all the file into memory and Python (at least the fraca7's port) have only about 17mb ram available for the script.

Does OGG playback stream the file?

Many thanks, it seems a very good port to me. :)

EDIT: Maybe you can use this to retrieve file info (you can use it after MP3_Load()).
If you want here you can also find code to read the ID3v1 tag:
http://forums.ps2dev.org/viewtopic.php? ... hlight=id3

Code: Select all

struct MP3Info
{
	int fileSize;
	char layer[10];
	int kbit;
	long hz;
	char mode[50];
	char emphasis[10];
	mad_timer_t length;
	char strLength[10];
	int frames;
};


void getInfo(){
	int FrameCount = 0;
	struct mad_stream stream;
	struct mad_header header; 
	mad_stream_init (&stream);
	mad_header_init (&header);

	MP3_info.fileSize = size;
	mad_timer_reset(&MP3_info.length);
	mad_stream_buffer (&stream, ptr, size);
	while (1){
		if (mad_header_decode (&header, &stream) == -1){
			if (MAD_RECOVERABLE(stream.error)){
				continue;				
			}else{
				break;
			}
		}
		//Informazioni solo dal primo frame:
	    if (FrameCount == 0){
			switch (header.layer) {
			case MAD_LAYER_I:
				strcpy(MP3_info.layer,"I");
				break;
			case MAD_LAYER_II:
				strcpy(MP3_info.layer,"II");
				break;
			case MAD_LAYER_III:
				strcpy(MP3_info.layer,"III");
				break;
			default:
				strcpy(MP3_info.layer,"unknown");
				break;
			}

			MP3_info.kbit = header.bitrate / 1000;
			MP3_info.hz = header.samplerate;
			switch (header.mode) {
			case MAD_MODE_SINGLE_CHANNEL:
				strcpy(MP3_info.mode, "single channel");
				break;
			case MAD_MODE_DUAL_CHANNEL:
				strcpy(MP3_info.mode, "dual channel");
				break;
			case MAD_MODE_JOINT_STEREO:
				strcpy(MP3_info.mode, "joint (MS/intensity) stereo");
				break;
			case MAD_MODE_STEREO:
				strcpy(MP3_info.mode, "normal LR stereo");
				break;
			default:
				strcpy(MP3_info.mode, "unknown");
				break;
			}

			switch (header.emphasis) {
			case MAD_EMPHASIS_NONE:
				strcpy(MP3_info.emphasis,"no");
				break;
			case MAD_EMPHASIS_50_15_US:
				strcpy(MP3_info.emphasis,"50/15 us");
				break;
			case MAD_EMPHASIS_CCITT_J_17:
				strcpy(MP3_info.emphasis,"CCITT J.17");
				break;
			case MAD_EMPHASIS_RESERVED:
				strcpy(MP3_info.emphasis,"reserved(!)");
				break;
			default:
				strcpy(MP3_info.emphasis,"unknown");
				break;
			}			
		}
		//Conteggio frame e durata totale:
		FrameCount++;
		mad_timer_add (&MP3_info.length, header.duration);
	}
	mad_header_finish (&header);
	mad_stream_finish (&stream);

	MP3_info.frames = FrameCount;
	//Formatto in stringa la durata totale:
	mad_timer_string(MP3_info.length, MP3_info.strLength, "%02lu:%02u:%02u", MAD_UNITS_HOURS, MAD_UNITS_MILLISECONDS, 0);
}

struct MP3Info MP3_GetInfo()
{
	return MP3_info;
}

Ciaooo
Sakya
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

Sorry for the delay guys, the modules are currently functional but I started working together with Ghoti on a streaming approach for mp3.

It would ease up a lot of memory since the music wont be loaded entirely into RAM.

In a few more days I will have a fully streaming support for the MP3 part and hopefully I will mimic this functionality into the OGG one.

Hope you guys understand.... for now... keep playing and learning Stackless Python.

I have an examples project... take a look on: http://code.google.com/p/stacklessexamp ... ssExamples

Here you will find some use-cases for it....

And of course... my first tutorial for Stackless PSP at: http://themindcaster.blogspot.com/2007/ ... art-1.html

Re
sakya
Posts: 190
Joined: Fri Apr 28, 2006 5:48 pm
Contact:

Post by sakya »

Hi! :)
carlosedp wrote: In a few more days I will have a fully streaming support for the MP3 part and hopefully I will mimic this functionality into the OGG one.
Wow, great! :)
I think I'll look at your code for the streaming... :D
I'm a noob and I tried to stream data to libMad and...well I think I have to study C for more time. ;)

EDIT: Just curiosity: are you going to use libMad or libaudiocodec?

Ciaooo
Sakya
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

I will use libMad for MP3 and libTremor for OGG.

Since Ghoti is going to help me on this streaming functionality, he is the one worth the credits... i will wrap the functions and trim the edges to make it all work correctly... :)

Ciao..
Post Reply