platform: using hw psp mp3 decoder for streams

This commit is contained in:
Crow-bar
2022-11-21 11:14:22 +03:00
parent 15ea61ea34
commit 3ccb156554
6 changed files with 835 additions and 11 deletions
+485 -7
View File
@@ -12,8 +12,8 @@ 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.
*/
#include "soundlib.h"
#if !XASH_PSP
#include "libmpg/libmpg.h"
/*
@@ -117,12 +117,8 @@ stream_t *Stream_OpenMPG( const char *filename )
file_t *file;
int ret;
wavinfo_t sc;
#if XASH_PSP
// h - hold mode
file = FS_Open( filename, "rbh", false );
#else
file = FS_Open( filename, "rb", false );
#endif
if( !file ) return NULL;
// at this point we have valid stream
@@ -190,7 +186,7 @@ int Stream_ReadMPG( stream_t *stream, int needBytes, void *buffer )
// check remaining size
if( bytesWritten + stream->pos > needBytes )
outsize = ( needBytes - bytesWritten );
outsize = ( needBytes - bytesWritten );
else outsize = stream->pos;
// copy raw sample to output buffer
@@ -265,3 +261,485 @@ void Stream_FreeMPG( stream_t *stream )
Mem_Free( stream );
}
#else // XASH_PSP
#include "platform/psp/scemp3/pspmp3.h"
/*
=================================================================
PSP MPEG decoding
=================================================================
*/
#define MP3_ID3V1_ID "TAG"
#define MP3_ID3V1_ID_SZ 3
#define MP3_ID3V1_SZ 128
#define MP3_ID3V2_ID "ID3"
#define MP3_ID3V2_ID_SZ 3
#define MP3_ID3V2_SIZE_OFF 6
#define MP3_ID3V2_SIZE_SZ 4
#define MP3_ID3V2_HEADER_SZ 10
#define MP3_ERRORS_MAX 3
#define PCM_WIDTH 2 // always 16-bit PCM
#define PCM_CHANNELS 2 // always 2
#define MP3_BUFFER_SIZE ( 128 * 1024 )
#define PCM_BUFFER_SIZE (( 1152 * PCM_WIDTH * PCM_CHANNELS ) * 2 ) // framesample * width * channels * 2(double buffer)
typedef struct
{
int handle;
int cachePos;
int frameCount;
byte *pcmTempPtr;
} mp3_decoder_t;
/*
=================
Sound_GetID3V2SizeMPG
=================
*/
__inline int Sound_GetID3V2SizeMPG( const byte *tagSize )
{
int size;
byte *sizePtr = (byte*)&size;
// 7 bit per byte, invert endian
sizePtr[0] = (( tagSize[3] >> 0 ) & 0x7F ) | (( tagSize[2] & 0x01 ) << 7 );
sizePtr[1] = (( tagSize[2] >> 1 ) & 0x3F ) | (( tagSize[1] & 0x03 ) << 6 );
sizePtr[2] = (( tagSize[1] >> 2 ) & 0x1F ) | (( tagSize[0] & 0x07 ) << 5 );
sizePtr[3] = (( tagSize[0] >> 3 ) & 0x0F );
return size;
}
#if 0
/*
=================
Sound_FindHeadMPG
=================
*/
fs_offset_t Sound_FindHeadMPG( const byte *buffer, fs_offset_t filesize )
{
fs_offset_t result;
result = 0;
if( filesize >= MP3_ID3V2_HEADER_SZ )
{
if( !memcmp( buffer, MP3_ID3V2_ID, MP3_ID3V2_ID_SZ ))
result = Sound_GetID3V2SizeMPG( &buffer[MP3_ID3V2_SIZE_OFF] ) + MP3_ID3V2_HEADER_SZ;
}
return result;
}
/*
=================
Sound_FindTailMPG
=================
*/
fs_offset_t Sound_FindTailMPG( const byte *buffer, fs_offset_t filesize )
{
fs_offset_t result;
result = filesize;
if( filesize >= MP3_ID3V1_SZ )
{
if( !memcmp( &buffer[filesize - MP3_ID3V1_SZ], MP3_ID3V1_ID, MP3_ID3V1_ID_SZ ))
result -= MP3_ID3V1_SZ;
}
return result;
}
#endif
qboolean Sound_LoadMPG( const char *name, const byte *buffer, fs_offset_t filesize )
{
#if 0
int status;
int handle;
size_t bytesWrite = 0;
byte out[PCM_BUFFER_SIZE] __attribute__((aligned(64)));
fs_offset_t headOffset;
fs_offset_t tailOffset;
fs_offset_t contentSize;
int frameSample;
uint bps;
int frameLen;
int frameSize;
int frameCount;
headOffset = Sound_FindHeadMPG( buffer, filesize );
tailOffset = Sound_FindTailMPG( buffer, filesize );
contentSize = tailOffset - headOffset;
// TODO: read Xing header
handle = sceMp3ReserveMp3Handle( NULL );
if ( handle < 0 )
{
Con_DPrintf( S_ERROR "sceMp3ReserveMp3Handle returned 0x%08X\n", handle );
return false;
}
status = sceMp3LowLevelInit( handle, &buffer[headOffset] );
if ( status < 0 )
{
Con_DPrintf( S_ERROR "sceMp3LowLevelInit returned 0x%08X\n", status );
return false;
}
frameSample = sceMp3GetMaxOutputSample( handle );
frameSize = (( frameSample / 8 ) * sceMp3GetBitRate( handle ) * 1000 ) / sceMp3GetSamplingRate( handle );
frameCount = contentSize / frameSize;
sound.channels = sceMp3GetMp3ChannelNum( handle );
sound.rate = sceMp3GetSamplingRate( handle );
sound.width = PCM_WIDTH; // always 16-bit PCM
sound.loopstart = -1;
sound.size = (frameCount * frameSample) * sound.channels * sound.width; // invalid for VBR
/*
status = sceMp3LowLevelDecode(handle, &buffer[headOffset + mp3usedsize], &mp3usedsize, pcm, &pcmoutsize);
if(status < 0)
{
Con_DPrintf( S_ERROR "sceMp3LowLevelDecode returned 0x%08X\n", status);
}
sceMp3ReleaseMp3Handle( handle );
*/
return true;
#else
Con_DPrintf( S_ERROR "Sound_LoadMPG unimplemented function!\n");
return false;
#endif
}
/*
=================
Stream_FindHeadMPG
=================
*/
SceOff Stream_FindHeadMPG( file_t *file )
{
SceOff result;
byte tagId[MP3_ID3V2_ID_SZ];
byte tagSize[MP3_ID3V2_SIZE_SZ];
result = 0;
FS_Seek( file, 0, SEEK_SET );
if( FS_Read( file, tagId, MP3_ID3V2_ID_SZ) < MP3_ID3V2_ID_SZ )
{
Con_DPrintf( S_ERROR "Sound_Mp3FindHead: ID3V2 ID read error\n");
return result;
}
if( !memcmp( tagId, MP3_ID3V2_ID, MP3_ID3V2_ID_SZ ))
{
FS_Seek( file, MP3_ID3V2_SIZE_OFF, SEEK_SET );
if( FS_Read( file, tagSize, MP3_ID3V2_SIZE_SZ ) < MP3_ID3V2_SIZE_SZ )
Con_DPrintf( S_ERROR "Sound_Mp3FindHead: ID3V2 SIZE read error\n");
else result = Sound_GetID3V2SizeMPG( tagSize ) + MP3_ID3V2_HEADER_SZ;
}
return result;
}
/*
=================
Stream_FindTailMPG
=================
*/
SceOff Stream_FindTailMPG( file_t *file )
{
SceOff result;
byte tagId[MP3_ID3V1_ID_SZ];
result = FS_FileLength( file );
FS_Seek( file, result - MP3_ID3V1_SZ, SEEK_SET );
if( FS_Read( file, tagId, MP3_ID3V1_ID_SZ ) < MP3_ID3V1_ID_SZ )
{
Con_DPrintf( S_ERROR "Sound_Mp3FindTail: ID3V1 ID read error\n");
return result;
}
if( !memcmp( tagId, MP3_ID3V1_ID, MP3_ID3V1_ID_SZ ))
result -= MP3_ID3V1_SZ;
return result;
}
/*
=================
Stream_FillBufferMPG
=================
*/
int Stream_FillBufferMPG( file_t *file, mp3_decoder_t *desc )
{
int status;
byte *dstPtr;
int dstSize;
int dstPos;
fs_offset_t readSize;
if( sceMp3CheckStreamDataNeeded( desc->handle ) <= 0 )
return 0;
// get Info on the stream (where to fill to, how much to fill, where to fill from)
status = sceMp3GetInfoToAddStreamData( desc->handle, &dstPtr, &dstSize, &dstPos );
if( status < 0 )
{
Con_DPrintf( S_ERROR "sceMp3GetInfoToAddStreamData returned 0x%08X\n", status);
return status;
}
// seek file to position requested
if( desc->cachePos != dstPos )
{
FS_Seek( file, dstPos, SEEK_SET );
desc->cachePos = dstPos;
}
// read the amount of data
readSize = FS_Read( file, dstPtr, dstSize );
desc->cachePos += ( int )readSize;
// notify mp3 library about how much we really wrote to the stream buffer
status = sceMp3NotifyAddStreamData( desc->handle, ( int )readSize );
if ( status < 0 )
Con_DPrintf( S_ERROR "sceMp3NotifyAddStreamData returned 0x%08X\n", status);
return status;
}
/*
=================
Stream_OpenMPG
=================
*/
stream_t *Stream_OpenMPG( const char *filename )
{
stream_t *stream;
mp3_decoder_t *desc;
file_t *file;
int status;
void *bufferBase;
file = FS_Open( filename, "rbh", false ); // hold mode
if( !file ) return NULL;
// at this point we have valid stream
stream = Mem_Calloc( host.soundpool, sizeof( stream_t ));
stream->file = file;
stream->pos = 0;
desc = Mem_Calloc( host.soundpool, sizeof( mp3_decoder_t ) + MP3_BUFFER_SIZE + PCM_BUFFER_SIZE + 63 );
bufferBase = (void *)(((( uintptr_t )desc + sizeof( mp3_decoder_t )) & (~( 64 - 1 ))) + 64 );
// reserve a mp3 handle
SceMp3InitArg mp3Init;
mp3Init.mp3StreamStart = Stream_FindHeadMPG( file );
mp3Init.mp3StreamEnd = Stream_FindTailMPG( file );
mp3Init.mp3Buf = bufferBase;
mp3Init.mp3BufSize = MP3_BUFFER_SIZE;
mp3Init.pcmBuf = (void *)(( uintptr_t )bufferBase + MP3_BUFFER_SIZE );
mp3Init.pcmBufSize = PCM_BUFFER_SIZE;
desc->cachePos = 0;
desc->pcmTempPtr = mp3Init.pcmBuf;
desc->handle = sceMp3ReserveMp3Handle( &mp3Init );
if ( desc->handle < 0 )
{
Con_DPrintf( S_ERROR "sceMp3ReserveMp3Handle returned 0x%08X\n", desc->handle );
Mem_Free( stream );
Mem_Free( desc );
FS_Close( file );
return NULL;
}
// Fill the stream buffer with some data so that sceMp3Init has something to work with
if( Stream_FillBufferMPG( file, desc ) != 0 )
{
Mem_Free( stream );
Mem_Free( desc );
FS_Close( file );
return NULL;
}
status = sceMp3Init( desc->handle );
if ( status < 0 )
{
Con_DPrintf( S_ERROR "sceMp3Init returned 0x%08X\n", status );
Mem_Free( stream );
Mem_Free( desc );
FS_Close( file );
return NULL;
}
desc->frameCount = sceMp3GetFrameNum( desc->handle );
stream->buffsize = 0; // how many samples left from previous frame
stream->channels = PCM_CHANNELS; // always 2 PCM channels
stream->rate = sceMp3GetSamplingRate( desc->handle );
stream->width = PCM_WIDTH; // always 16 bit PCM
stream->ptr = (void *)desc;
stream->type = WF_MPGDATA;
return stream;
}
/*
=================
Stream_ReadMPG
assume stream is valid
=================
*/
int Stream_ReadMPG( stream_t *stream, int needBytes, void *buffer )
{
// buffer handling
int bytesWritten = 0;
mp3_decoder_t *desc;
int errdec;
desc = ( mp3_decoder_t* )stream->ptr;
while(1)
{
byte *data;
int outsize;
if( !stream->buffsize )
{
// Check if we need to fill our stream buffer
if( Stream_FillBufferMPG( stream->file, desc ) != 0 )
return 0;
for( errdec = 0; errdec < MP3_ERRORS_MAX; errdec++ )
{
stream->pos = sceMp3Decode( desc->handle, (SceShort16**)&desc->pcmTempPtr );
if(( int )stream->pos >= 0 ) // decoding successful
{
break;
}
else if( stream->pos == 0x80671402 ) // next frame header
{
if( Stream_FillBufferMPG( stream->file, desc ) != 0 )
return 0;
}
else break;
}
if(( int )stream->pos < 0 )
{
if( stream->pos != 0x80671402 )
Con_DPrintf( S_ERROR "sceMp3Decode returned 0x%08X\n", stream->pos );
return 0; // ???
}
}
// check remaining size
if( bytesWritten + stream->pos > needBytes )
outsize = ( needBytes - bytesWritten );
else outsize = stream->pos;
// copy raw sample to output buffer
data = (byte *)buffer + bytesWritten;
memcpy( data, &desc->pcmTempPtr[stream->buffsize], outsize );
bytesWritten += outsize;
stream->pos -= outsize;
stream->buffsize += outsize;
// continue from this sample on a next call
if( bytesWritten >= needBytes )
return bytesWritten;
stream->buffsize = 0; // no bytes remaining
}
return 0;
}
/*
=================
Stream_SetPosMPG
assume stream is valid
=================
*/
int Stream_SetPosMPG( stream_t *stream, int newpos )
{
mp3_decoder_t *desc;
int frame;
int status;
desc = ( mp3_decoder_t* )stream->ptr;
// get frame num
frame = newpos / sceMp3GetMaxOutputSample( desc->handle ); // VBR?
if( frame < 1 || frame >= desc->frameCount - 1 )
return false;
status = sceMp3ResetPlayPositionByFrame( desc->handle, frame );
if( status < 0 )
{
Con_DPrintf( S_ERROR "sceMp3ResetPlayPositionByFrame returned 0x%08X\n", status );
// failed to seek for some reasons
return false;
}
// flush any previous data
stream->buffsize = 0;
return true;
}
/*
=================
Stream_GetPosMPG
assume stream is valid
=================
*/
int Stream_GetPosMPG( stream_t *stream )
{
mp3_decoder_t *desc;
desc = ( mp3_decoder_t * )stream->ptr;
return sceMp3GetSumDecodedSample( desc->handle );
}
/*
=================
Stream_FreeMPG
assume stream is valid
=================
*/
void Stream_FreeMPG( stream_t *stream )
{
mp3_decoder_t *desc;
desc = ( mp3_decoder_t * )stream->ptr;
if( desc )
{
sceMp3ReleaseMp3Handle( desc->handle );
Mem_Free( desc );
stream->ptr = NULL;
}
if( stream->file )
{
FS_Close( stream->file );
stream->file = NULL;
}
Mem_Free( stream );
}
#endif // XASH_PSP
+2
View File
@@ -74,7 +74,9 @@ struct stream_s
// current stream state
void *ptr; // internal decoder state
#if !XASH_PSP
char temp[OUTBUF_SIZE]; // mpeg decoder stuff
#endif
size_t pos; // actual track position (or actual buffer remains)
int buffsize; // cached buffer size
};
+248
View File
@@ -0,0 +1,248 @@
/*
* PSP Software Development Kit - https://github.com/pspdev
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* pspmp3.h - Prototypes for the sceMp3 library
*
* Copyright (c) 2008 David Perry <tias_dp@hotmail.com>
* Copyright (c) 2008 Alexander Berl <raphael@fx-world.org>
* Copyright (c) 2022 Sergey Galushko
*
*/
#ifndef __SCELIBMP3_H__
#define __SCELIBMP3_H__
#include <psptypes.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct SceMp3InitArg {
/** Stream start position */
SceOff mp3StreamStart;
/** Stream end position */
SceOff mp3StreamEnd;
/** Pointer to a buffer to contain raw mp3 stream data (+1472 bytes workspace) */
SceUChar8* mp3Buf;
/** Size of mp3Buf buffer (must be >= 8192) */
SceInt32 mp3BufSize;
/** Pointer to decoded pcm samples buffer */
SceUChar8* pcmBuf;
/** Size of pcmBuf buffer (must be >= 9216) */
SceInt32 pcmBufSize;
} SceMp3InitArg;
/**
* sceMp3ReserveMp3Handle
*
* @param args - Pointer to SceMp3InitArg structure
*
* @return sceMp3 handle on success, < 0 on error.
*/
SceInt32 sceMp3ReserveMp3Handle(SceMp3InitArg* args);
/**
* sceMp3ReleaseMp3Handle
*
* @param handle - sceMp3 handle
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3ReleaseMp3Handle(SceInt32 handle);
/**
* sceMp3InitResource
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3InitResource();
/**
* sceMp3TermResource
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3TermResource();
/**
* sceMp3Init
*
* @param handle - sceMp3 handle
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3Init(SceInt32 handle);
/**
* sceMp3Decode
*
* @param handle - sceMp3 handle
* @param dst - Pointer to destination pcm samples buffer
*
* @return number of bytes in decoded pcm buffer, < 0 on error.
*/
SceInt32 sceMp3Decode(SceInt32 handle, SceShort16** dst);
/**
* sceMp3GetInfoToAddStreamData
*
* @param handle - sceMp3 handle
* @param dst - Pointer to stream data buffer
* @param towrite - Space remaining in stream data buffer
* @param srcpos - Position in source stream to start reading from
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3GetInfoToAddStreamData(SceInt32 handle, SceUChar8** dst, SceInt32* towrite, SceInt32* srcpos);
/**
* sceMp3NotifyAddStreamData
*
* @param handle - sceMp3 handle
* @param size - number of bytes added to the stream data buffer
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3NotifyAddStreamData(SceInt32 handle, SceInt32 size);
/**
* sceMp3CheckStreamDataNeeded
*
* @param handle - sceMp3 handle
*
* @return 1 if more stream data is needed, < 0 on error.
*/
SceInt32 sceMp3CheckStreamDataNeeded(SceInt32 handle);
/**
* sceMp3SetLoopNum
*
* @param handle - sceMp3 handle
* @param loop - Number of loops
*
* @return 0 if success, < 0 on error.
*/
SceInt32 sceMp3SetLoopNum(SceInt32 handle, SceInt32 loop);
/**
* sceMp3GetLoopNum
*
* @param handle - sceMp3 handle
*
* @return Number of loops
*/
SceInt32 sceMp3GetLoopNum(SceInt32 handle);
/**
* sceMp3GetSumDecodedSample
*
* @param handle - sceMp3 handle
*
* @return Number of decoded samples
*/
SceInt32 sceMp3GetSumDecodedSample(SceInt32 handle);
/**
* sceMp3GetMaxOutputSample
*
* @param handle - sceMp3 handle
*
* @return Number of max samples to output
*/
SceInt32 sceMp3GetMaxOutputSample(SceInt32 handle);
/**
* sceMp3GetSamplingRate
*
* @param handle - sceMp3 handle
*
* @return Sampling rate of the mp3
*/
SceInt32 sceMp3GetSamplingRate(SceInt32 handle);
/**
* sceMp3GetBitRate
*
* @param handle - sceMp3 handle
*
* @return Bitrate of the mp3
*/
SceInt32 sceMp3GetBitRate(SceInt32 handle);
/**
* sceMp3GetMp3ChannelNum
*
* @param handle - sceMp3 handle
*
* @return Number of channels of the mp3
*/
SceInt32 sceMp3GetMp3ChannelNum(SceInt32 handle);
/**
* sceMp3ResetPlayPosition
*
* @param handle - sceMp3 handle
*
* @return < 0 on error
*/
SceInt32 sceMp3ResetPlayPosition(SceInt32 handle);
/**
* sceMp3GetFrameNum
*
* @param handle - sceMp3 handle
*
* @return < 0 on error
*/
SceInt32 sceMp3GetFrameNum(SceInt32 handle);
/**
* sceMp3ResetPlayPositionByFrame
*
* @param handle - sceMp3 handle
* @param frame - frame
*
* @return < 0 on error
*/
SceInt32 sceMp3ResetPlayPositionByFrame(SceInt32 handle, SceUInt32 frame);
/**
* sceMp3GetMPEGVersion
*
* @param handle - sceMp3 handle
*
* @return < 0 on error
*/
SceInt32 sceMp3GetMPEGVersion(SceInt32 handle);
/**
* sceMp3LowLevelInit
*
* @param handle - sceMp3 handle
* @param src - Pointer to a buffer to contain raw mp3 stream data
*
* @return < 0 on error
*/
SceInt32 sceMp3LowLevelInit(SceInt32 handle, SceUChar8* src);
/**
* sceMp3LowLevelDecode
*
* @param handle - sceMp3 handle
* @param mp3src -
* @param mp3srcused -
* @param pcmdst -
* @param pcmdstoutsz -
*
* @return < 0 on error
*/
SceInt32 sceMp3LowLevelDecode(SceInt32 handle, SceUChar8* mp3src, SceUInt32* mp3srcused, SceShort16* pcmdst, SceUInt32* pcmdstoutsz);
#ifdef __cplusplus
}
#endif
#endif
+29
View File
@@ -0,0 +1,29 @@
.set noreorder
#include "pspimport.s"
IMPORT_START "sceMp3",0x00090011
IMPORT_FUNC "sceMp3",0x07EC321A,sceMp3ReserveMp3Handle
IMPORT_FUNC "sceMp3",0x0DB149F4,sceMp3NotifyAddStreamData
IMPORT_FUNC "sceMp3",0x2A368661,sceMp3ResetPlayPosition
IMPORT_FUNC "sceMp3",0x354D27EA,sceMp3GetSumDecodedSample
IMPORT_FUNC "sceMp3",0x35750070,sceMp3InitResource
IMPORT_FUNC "sceMp3",0x3C2FA058,sceMp3TermResource
IMPORT_FUNC "sceMp3",0x3CEF484F,sceMp3SetLoopNum
IMPORT_FUNC "sceMp3",0x44E07129,sceMp3Init
IMPORT_FUNC "sceMp3",0x732B042A,sceMp3EndEntry
IMPORT_FUNC "sceMp3",0x7F696782,sceMp3GetMp3ChannelNum
IMPORT_FUNC "sceMp3",0x87677E40,sceMp3GetBitRate
IMPORT_FUNC "sceMp3",0x87C263D1,sceMp3GetMaxOutputSample
IMPORT_FUNC "sceMp3",0x8AB81558,sceMp3StartEntry
IMPORT_FUNC "sceMp3",0x8F450998,sceMp3GetSamplingRate
IMPORT_FUNC "sceMp3",0xA703FE0F,sceMp3GetInfoToAddStreamData
IMPORT_FUNC "sceMp3",0xD021C0FB,sceMp3Decode
IMPORT_FUNC "sceMp3",0xD0A56296,sceMp3CheckStreamDataNeeded
IMPORT_FUNC "sceMp3",0xD8F54A51,sceMp3GetLoopNum
IMPORT_FUNC "sceMp3",0xF5478233,sceMp3ReleaseMp3Handle
IMPORT_FUNC "sceMp3",0xAE6D2027,sceMp3GetMPEGVersion
IMPORT_FUNC "sceMp3",0x3548AEC8,sceMp3GetFrameNum
IMPORT_FUNC "sceMp3",0x0840E808,sceMp3ResetPlayPositionByFrame
IMPORT_FUNC "sceMp3",0x1B839B83,sceMp3LowLevelInit
IMPORT_FUNC "sceMp3",0xE3EE2C81,sceMp3LowLevelDecode
+68 -3
View File
@@ -15,12 +15,14 @@ GNU General Public License for more details.
#include "platform/platform.h"
#include "platform/psp/ka/ka.h"
#include "platform/psp/scemp3/pspmp3.h"
#include <pspsdk.h>
#include <pspkernel.h>
#include <psppower.h>
#include <psprtc.h>
#include <pspprof.h>
#include <pspctrl.h>
#include <psputility.h>
#include <ctype.h>
@@ -30,6 +32,8 @@ PSP_MAIN_THREAD_ATTR( PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU );
PSP_MAIN_THREAD_STACK_SIZE_KB( 512 );
PSP_HEAP_SIZE_KB( -3 * 1024 ); /* 3 MB for prx modules */
static qboolean psp_audiolib_init = false;
static int Platform_ExitCallback( int count, int arg, void *common )
{
host.crashed = true;
@@ -251,10 +255,68 @@ int Platform_UnloadModule( SceUID modid, int *sce_code )
return ( ( ( *sce_code ) < 0 ) ? -2 : 0 );
}
int Platform_InitAudioLibs( void )
{
int status;
if( psp_audiolib_init )
return -1;
status = sceUtilityLoadModule( PSP_MODULE_AV_AVCODEC );
if ( status < 0 )
{
Con_DPrintf( S_ERROR "sceUtilityLoadModule(PSP_MODULE_AV_AVCODEC) returned 0x%08X\n", status );
return status;
}
status = sceUtilityLoadModule( PSP_MODULE_AV_MP3 );
if ( status < 0 )
{
Con_DPrintf( S_ERROR "sceUtilityLoadModule(PSP_MODULE_AV_MP3) returned 0x%08X\n", status );
return status;
}
// init mp3 resources
status = sceMp3InitResource();
if ( status < 0 )
{
Con_DPrintf( S_ERROR "sceMp3InitResource returned 0x%08X\n", status );
return status;
}
psp_audiolib_init = true;
return 0;
}
int Platform_ShutdownAudioLibs( void )
{
int status;
if( !psp_audiolib_init )
return -1;
status = sceMp3TermResource();
if ( status < 0 )
Con_DPrintf( S_ERROR "sceMp3TermResource returned 0x%08X\n", status );
status = sceUtilityUnloadModule( PSP_MODULE_AV_MP3 );
if ( status < 0 )
Con_DPrintf( S_ERROR "sceUtilityUnloadModule(PSP_MODULE_AV_MP3) returned 0x%08X\n", status );
status = sceUtilityUnloadModule( PSP_MODULE_AV_AVCODEC );
if ( status < 0 )
Con_DPrintf( S_ERROR "sceUtilityUnloadModule(PSP_MODULE_AV_AVCODEC) returned 0x%08X\n", status );
psp_audiolib_init = false;
return 0;
}
void Platform_Init( void )
{
SceUID kamID;
int result;
SceUID kamID;
int result;
// disable fpu exceptions (division by zero and etc...)
pspSdkDisableFPUExceptions();
@@ -275,13 +337,16 @@ void Platform_Init( void )
Platform_UnloadModule( kamID, &result );
}
Platform_InitAudioLibs();
// P5 Ram init
P5Ram_Init();
P5Ram_Init();
}
void Platform_Shutdown( void )
{
P5Ram_Shutdown();
Platform_ShutdownAudioLibs();
#if XASH_PROFILING
gprof_cleanup();
#endif
+3 -1
View File
@@ -95,9 +95,11 @@ def build(bld):
'common/*.c',
'common/imagelib/*.c',
'common/soundlib/*.c',
'common/soundlib/libmpg/*.c',
'server/*.c'])
if bld.env.DEST_OS != 'psp':
source += bld.path.ant_glob(['common/soundlib/libmpg/*.c'])
# basic build: dedicated only, no dependencies
if bld.env.DEST_OS == 'win32':
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32' ]