2012-11-01 15:19:01 +00:00
// Copyright (c) 2012- PPSSPP Project.
// 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
2012-11-04 22:01:49 +00:00
// the Free Software Foundation, version 2.0 or later versions.
2012-11-01 15:19:01 +00:00
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2012-12-09 12:41:19 +00:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2012-11-01 15:19:01 +00:00
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
# include "../MIPS/MIPS.h"
# include "../Host.h"
# include "../../Core/CoreTiming.h"
# include "sceAudio.h"
# include "__sceAudio.h"
# include "HLE.h"
2012-11-07 18:10:52 +00:00
// There's a second Audio api called Audio2 that only has one channel, I guess the 8 channel api was overkill.
// We simply map it to the first of the 8 channels.
2012-11-01 15:19:01 +00:00
AudioChannel chans [ 8 ] ;
// Enqueues the buffer pointer on the channel. If channel buffer queue is full (2 items?) will block until it isn't.
// For solid audio output we'll need a queue length of 2 buffers at least, we'll try that first.
// Not sure about the range of volume, I often see 0x800 so that might be either
// max or 50%?
2012-11-17 13:20:04 +00:00
2012-12-09 12:41:19 +00:00
u32 sceAudioOutputBlocking ( u32 chan , u32 vol , u32 samplePtr ) {
if ( samplePtr = = 0 ) {
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutputBlocking - Sample pointer null " ) ;
2012-12-09 12:41:19 +00:00
return 0 ;
2012-11-17 13:20:04 +00:00
}
2012-12-09 12:41:19 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL ) {
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutputBlocking() - BAD CHANNEL " ) ;
2012-12-09 12:41:19 +00:00
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
} else if ( ! chans [ chan ] . reserved ) {
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutputBlocking() - channel not reserved " ) ;
2012-12-09 12:41:19 +00:00
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
} else {
2012-11-17 13:20:04 +00:00
DEBUG_LOG ( HLE , " sceAudioOutputBlocking(%d, %d, %08x ) " , chan , vol , samplePtr ) ;
chans [ chan ] . leftVolume = vol ;
chans [ chan ] . rightVolume = vol ;
chans [ chan ] . sampleAddress = samplePtr ;
2012-12-09 12:41:19 +00:00
return __AudioEnqueue ( chans [ chan ] , chan , true ) ;
2012-11-17 13:20:04 +00:00
}
}
2012-12-09 12:41:19 +00:00
u32 sceAudioOutputPannedBlocking ( u32 chan , u32 volume1 , u32 volume2 , u32 samplePtr ) {
if ( samplePtr = = 0 ) {
ERROR_LOG ( HLE , " sceAudioOutputPannedBlocking - Sample pointer null " ) ;
return 0 ;
} else if ( chan < 0 | | chan > = MAX_CHANNEL ) {
2012-11-01 15:19:01 +00:00
ERROR_LOG ( HLE , " sceAudioOutputPannedBlocking() - BAD CHANNEL " ) ;
2012-12-09 12:41:19 +00:00
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
} else if ( ! chans [ chan ] . reserved ) {
2012-11-08 15:28:45 +00:00
ERROR_LOG ( HLE , " sceAudioOutputPannedBlocking() - CHANNEL NOT RESERVED " ) ;
2012-12-09 12:41:19 +00:00
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
} else {
DEBUG_LOG ( HLE , " sceAudioOutputPannedBlocking(%d,%d,%d, %08x ) " , chan , volume1 , volume2 , samplePtr ) ;
2012-11-01 15:19:01 +00:00
chans [ chan ] . leftVolume = volume1 ;
chans [ chan ] . rightVolume = volume2 ;
chans [ chan ] . sampleAddress = samplePtr ;
2012-12-09 12:41:19 +00:00
return __AudioEnqueue ( chans [ chan ] , chan , true ) ;
2012-11-01 15:19:01 +00:00
}
}
2012-11-17 13:20:04 +00:00
u32 sceAudioOutput ( u32 chan , u32 vol , u32 samplePtr )
2012-11-01 15:19:01 +00:00
{
2012-12-09 12:41:19 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL ) {
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutput() - BAD CHANNEL " ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
else if ( ! chans [ chan ] . reserved )
{
ERROR_LOG ( HLE , " sceAudioOutput(%d, %d, %08x) - channel not reserved " , chan , vol , samplePtr ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
else
{
chans [ chan ] . leftVolume = vol ;
chans [ chan ] . rightVolume = vol ;
2012-11-01 15:19:01 +00:00
chans [ chan ] . sampleAddress = samplePtr ;
2012-11-17 13:20:04 +00:00
u32 retval = __AudioEnqueue ( chans [ chan ] , chan , false ) ;
DEBUG_LOG ( HLE , " %08x=sceAudioOutputPanned(%d, %d, %08x) " , retval , chan , vol , samplePtr ) ;
return retval ;
2012-11-01 15:19:01 +00:00
}
}
2012-11-17 13:20:04 +00:00
u32 sceAudioOutputPanned ( u32 chan , u32 leftVol , u32 rightVol , u32 samplePtr )
2012-11-01 15:19:01 +00:00
{
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutputPanned() - BAD CHANNEL " ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
2012-11-01 15:19:01 +00:00
}
2012-11-17 13:20:04 +00:00
else if ( ! chans [ chan ] . reserved )
2012-11-01 15:19:01 +00:00
{
2012-11-17 13:20:04 +00:00
ERROR_LOG ( HLE , " sceAudioOutputPanned(%d, %d, %d, %08x) - channel not reserved " , chan , leftVol , rightVol , samplePtr ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
else
{
chans [ chan ] . leftVolume = leftVol ;
chans [ chan ] . rightVolume = rightVol ;
2012-11-01 15:19:01 +00:00
chans [ chan ] . sampleAddress = samplePtr ;
2012-11-17 13:20:04 +00:00
u32 retval = __AudioEnqueue ( chans [ chan ] , chan , false ) ;
DEBUG_LOG ( HLE , " %08x=sceAudioOutputPanned(%d, %d, %d, %08x) " , retval , chan , leftVol , rightVol , samplePtr ) ;
return retval ;
2012-11-01 15:19:01 +00:00
}
}
2012-11-17 13:20:04 +00:00
int sceAudioGetChannelRestLen ( u32 chan )
{
2012-11-24 00:25:26 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioGetChannelRestLen(%i) - BAD CHANNEL " , chan ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
2012-11-17 13:20:04 +00:00
int sz = ( int ) chans [ chan ] . sampleQueue . size ( ) / 2 ;
2012-11-18 22:35:02 +00:00
DEBUG_LOG ( HLE , " UNTESTED %i = sceAudioGetChannelRestLen(%i) " , sz , chan ) ;
2012-11-17 13:20:04 +00:00
return sz ;
}
int sceAudioGetChannelRestLength ( u32 chan )
{
2012-11-24 00:25:26 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioGetChannelRestLength(%i) - BAD CHANNEL " , chan ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
2012-11-17 13:20:04 +00:00
int sz = ( int ) chans [ chan ] . sampleQueue . size ( ) / 2 ;
2012-11-18 22:35:02 +00:00
DEBUG_LOG ( HLE , " UNTESTED %i = sceAudioGetChannelRestLen(%i) " , sz , chan ) ;
2012-11-17 13:20:04 +00:00
return sz ;
}
2012-11-01 15:19:01 +00:00
static int GetFreeChannel ( )
{
for ( int i = 0 ; i < MAX_CHANNEL ; i + + )
2012-12-09 12:41:19 +00:00
{
2012-11-01 15:19:01 +00:00
if ( ! chans [ i ] . reserved )
{
return i ;
}
}
return - 1 ;
}
u32 sceAudioChReserve ( u32 channel , u32 sampleCount , u32 format ) //.Allocate sound channel
{
if ( channel = = ( u32 ) - 1 )
{
channel = GetFreeChannel ( ) ;
}
else
{
ERROR_LOG ( HLE , " sceAudioChReserve failed " ) ;
2012-11-24 00:25:26 +00:00
return SCE_ERROR_AUDIO_NO_CHANNELS_AVAILABLE ;
2012-11-01 15:19:01 +00:00
}
2012-11-24 00:25:26 +00:00
if ( channel < 0 | | channel > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioChReserve(channel = %d, sampleCount = %d, format = %d) - BAD CHANNEL " , channel , sampleCount , format ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
if ( format ! = PSP_AUDIO_FORMAT_MONO & & format ! = PSP_AUDIO_FORMAT_STEREO )
{
ERROR_LOG ( HLE , " sceAudioChReserve(channel = %d, sampleCount = %d, format = %d): invalid format " , channel , sampleCount , format ) ;
return SCE_ERROR_AUDIO_INVALID_FORMAT ;
}
2012-11-01 15:19:01 +00:00
if ( chans [ channel ] . reserved )
2012-11-24 00:25:26 +00:00
{
2012-11-01 15:19:01 +00:00
WARN_LOG ( HLE , " WARNING: Reserving already reserved channel. Error? " ) ;
}
2012-12-21 22:02:35 +00:00
DEBUG_LOG ( HLE , " sceAudioChReserve(channel = %d, sampleCount = %d, format = %d) " , channel , sampleCount , format ) ;
2012-11-01 15:19:01 +00:00
chans [ channel ] . sampleCount = sampleCount ;
chans [ channel ] . reserved = true ;
return channel ; //return handle
}
u32 sceAudioChRelease ( u32 chan )
{
2012-11-24 00:25:26 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioChRelease(%i) - BAD CHANNEL " , chan ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
if ( ! chans [ chan ] . reserved )
{
ERROR_LOG ( HLE , " sceAudioChRelease(%i): channel not reserved " , chan ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
2012-11-01 15:19:01 +00:00
chans [ chan ] . reserved = false ;
2012-11-17 13:20:04 +00:00
DEBUG_LOG ( HLE , " sceAudioChRelease(%i) " , chan ) ;
2012-11-01 15:19:01 +00:00
return 1 ;
}
u32 sceAudioSetChannelDataLen ( u32 chan , u32 len )
{
2012-12-09 12:41:19 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioSetChannelDataLen(%i, %i) - BAD CHANNEL " , chan , len ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
else if ( ! chans [ chan ] . reserved )
{
ERROR_LOG ( HLE , " sceAudioSetChannelDataLen(%i, %i) - channel not reserved " , chan , len ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
else
{
2012-12-17 21:20:32 +00:00
DEBUG_LOG ( HLE , " sceAudioSetChannelDataLen(%i, %i) " , chan , len ) ;
2012-11-17 18:56:28 +00:00
chans [ chan ] . sampleCount = len ;
2012-12-09 12:41:19 +00:00
return 0 ;
}
2012-11-01 15:19:01 +00:00
}
u32 sceAudioChangeChannelConfig ( u32 chan , u32 format )
{
2012-12-09 12:41:19 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioChangeChannelConfig(%i, %i) - invalid channel number " , chan , format ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
else if ( ! chans [ chan ] . reserved )
{
ERROR_LOG ( HLE , " sceAudioChangeChannelConfig(%i, %i) - channel not reserved " , chan , format ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
else
{
DEBUG_LOG ( HLE , " sceAudioChangeChannelConfig(%i, %i) " , chan , format ) ;
chans [ chan ] . format = format ;
return 0 ;
}
2012-11-01 15:19:01 +00:00
}
u32 sceAudioChangeChannelVolume ( u32 chan , u32 lvolume , u32 rvolume )
{
2012-12-09 12:41:19 +00:00
if ( chan < 0 | | chan > = MAX_CHANNEL )
{
ERROR_LOG ( HLE , " sceAudioChangeChannelVolume(%i, %i, %i) - invalid channel number " , chan , lvolume , rvolume ) ;
return SCE_ERROR_AUDIO_INVALID_CHANNEL ;
}
else if ( ! chans [ chan ] . reserved )
{
ERROR_LOG ( HLE , " sceAudioChangeChannelVolume(%i, %i, %i) - channel not reserved " , chan , lvolume , rvolume ) ;
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED ;
}
else
{
DEBUG_LOG ( HLE , " sceAudioChangeChannelVolume(%i, %i, %i) " , chan , lvolume , rvolume ) ;
chans [ chan ] . leftVolume = lvolume ;
chans [ chan ] . rightVolume = rvolume ;
return 0 ;
}
2012-11-01 15:19:01 +00:00
}
2012-11-27 11:18:58 +00:00
u32 sceAudioInit ( )
2012-11-01 15:19:01 +00:00
{
2012-11-27 11:18:58 +00:00
DEBUG_LOG ( HLE , " sceAudioInit() " ) ;
2012-11-17 18:56:28 +00:00
// Don't need to do anything
2012-11-27 11:18:58 +00:00
return 0 ;
2012-11-01 15:19:01 +00:00
}
2012-11-27 11:18:58 +00:00
u32 sceAudioEnd ( )
2012-11-17 18:56:28 +00:00
{
DEBUG_LOG ( HLE , " sceAudioEnd() " ) ;
// Don't need to do anything
2012-11-27 11:18:58 +00:00
return 0 ;
2012-11-17 18:56:28 +00:00
}
2012-11-01 15:19:01 +00:00
2012-11-27 11:18:58 +00:00
u32 sceAudioOutput2Reserve ( u32 sampleCount )
2012-11-07 18:10:52 +00:00
{
2012-12-20 14:06:38 +00:00
DEBUG_LOG ( HLE , " sceAudioOutput2Reserve(%i) " , sampleCount ) ;
2012-11-07 18:10:52 +00:00
chans [ 0 ] . sampleCount = sampleCount ;
chans [ 0 ] . reserved = true ;
2012-11-27 11:18:58 +00:00
return 0 ;
2012-11-07 18:10:52 +00:00
}
2012-12-09 12:41:19 +00:00
u32 sceAudioOutput2OutputBlocking ( u32 vol , u32 dataPtr )
2012-11-07 18:10:52 +00:00
{
2012-12-05 12:22:11 +00:00
DEBUG_LOG ( HLE , " FAKE sceAudioOutput2OutputBlocking(%i, %08x) " , vol , dataPtr ) ;
2012-11-07 18:10:52 +00:00
chans [ 0 ] . leftVolume = vol ;
chans [ 0 ] . rightVolume = vol ;
chans [ 0 ] . sampleAddress = dataPtr ;
2012-12-09 12:41:19 +00:00
return __AudioEnqueue ( chans [ 0 ] , 0 , true ) ;
2012-11-07 18:10:52 +00:00
}
2012-11-23 09:33:19 +00:00
u32 sceAudioOutput2ChangeLength ( u32 sampleCount )
2012-11-07 18:10:52 +00:00
{
2012-12-20 14:06:38 +00:00
DEBUG_LOG ( HLE , " sceAudioOutput2ChangeLength(%i) " , sampleCount ) ;
2012-11-23 09:33:19 +00:00
chans [ 0 ] . sampleCount = sampleCount ;
return 0 ;
2012-11-07 18:10:52 +00:00
}
2012-11-17 18:56:28 +00:00
u32 sceAudioOutput2GetRestSample ( )
2012-11-07 18:10:52 +00:00
{
2012-12-20 14:06:38 +00:00
DEBUG_LOG ( HLE , " UNTESTED sceAudioOutput2GetRestSample() " ) ;
2012-11-17 18:56:28 +00:00
return chans [ 0 ] . sampleQueue . size ( ) * 2 ;
2012-11-07 18:10:52 +00:00
}
2012-11-27 11:18:58 +00:00
u32 sceAudioOutput2Release ( )
2012-11-07 18:10:52 +00:00
{
2012-12-20 14:06:38 +00:00
DEBUG_LOG ( HLE , " sceAudioOutput2Release() " ) ;
2012-11-07 18:10:52 +00:00
chans [ 0 ] . reserved = false ;
2012-11-27 11:18:58 +00:00
return 0 ;
2012-11-07 18:10:52 +00:00
}
2012-11-17 13:20:04 +00:00
u32 sceAudioSetFrequency ( u32 freq ) {
if ( freq = = 44100 | | freq = = 48000 ) {
INFO_LOG ( HLE , " sceAudioSetFrequency(%i) " , freq ) ;
__AudioSetOutputFrequency ( freq ) ;
return 0 ;
} else {
ERROR_LOG ( HLE , " sceAudioSetFrequency(%i) - invalid frequency (must be 44.1 or 48 khz) " , freq ) ;
return - 1 ;
}
}
2012-12-17 19:15:23 +00:00
u32 sceAudioSetVolumeOffset ( u32 unknown ) {
ERROR_LOG ( HLE , " UNIMPL sceAudioSetVolumeOffset(%i) " , unknown ) ;
return 0 ;
}
2012-11-01 15:19:01 +00:00
const HLEFunction sceAudio [ ] =
{
2012-11-23 09:33:19 +00:00
// Newer simplified single channel audio output. Presumably for games that use Atrac3
// directly from Sas instead of playing it on a separate audio channel.
2012-12-09 12:41:19 +00:00
{ 0x01562ba3 , WrapU_U < sceAudioOutput2Reserve > , " sceAudioOutput2Reserve " } ,
{ 0x2d53f36e , WrapU_UU < sceAudioOutput2OutputBlocking > , " sceAudioOutput2OutputBlocking " } ,
{ 0x63f2889c , WrapU_U < sceAudioOutput2ChangeLength > , " sceAudioOutput2ChangeLength " } ,
{ 0x647cef33 , WrapU_V < sceAudioOutput2GetRestSample > , " sceAudioOutput2GetRestSample " } ,
{ 0x43196845 , WrapU_V < sceAudioOutput2Release > , " sceAudioOutput2Release " } ,
2012-11-06 15:20:13 +00:00
2012-11-27 11:18:58 +00:00
{ 0x80F1F7E0 , WrapU_V < sceAudioInit > , " sceAudioInit " } ,
{ 0x210567F7 , WrapU_V < sceAudioEnd > , " sceAudioEnd " } ,
2012-11-23 09:33:19 +00:00
2012-12-09 12:41:19 +00:00
{ 0xA2BEAA6C , WrapU_U < sceAudioSetFrequency > , " sceAudioSetFrequency " } ,
2012-12-17 19:15:23 +00:00
{ 0x927AC32B , WrapU_U < sceAudioSetVolumeOffset > , " sceAudioSetVolumeOffset " } ,
2012-11-23 09:33:19 +00:00
// The oldest and standard audio interface. Supports 8 channels, most games use 1-2.
2012-12-09 12:41:19 +00:00
{ 0x8c1009b2 , WrapU_UUU < sceAudioOutput > , " sceAudioOutput " } ,
{ 0x136CAF51 , WrapU_UUU < sceAudioOutputBlocking > , " sceAudioOutputBlocking " } ,
{ 0xE2D56B2D , WrapU_UUUU < sceAudioOutputPanned > , " sceAudioOutputPanned " } ,
{ 0x13F592BC , WrapU_UUUU < sceAudioOutputPannedBlocking > , " sceAudioOutputPannedBlocking " } , //(u32, u32, u32, void *)Output sound, blocking
{ 0x5EC81C55 , WrapU_UUU < sceAudioChReserve > , " sceAudioChReserve " } , //(u32, u32 samplecount, u32) Initialize channel and allocate buffer long, long samplecount, long);//init buffer? returns handle, minus if error
{ 0x6FC46853 , WrapU_U < sceAudioChRelease > , " sceAudioChRelease " } , //(long handle)Terminate channel and deallocate buffer //free buffer?
{ 0xE9D97901 , WrapI_U < sceAudioGetChannelRestLen > , " sceAudioGetChannelRestLen " } ,
{ 0xB011922F , WrapI_U < sceAudioGetChannelRestLen > , " sceAudioGetChannelRestLength " } , // Is there a difference between this and sceAudioGetChannelRestLen?
2012-11-17 13:20:04 +00:00
{ 0xCB2E439E , WrapU_UU < sceAudioSetChannelDataLen > , " sceAudioSetChannelDataLen " } , //(u32, u32)
2012-12-09 12:41:19 +00:00
{ 0x95FD0C2D , WrapU_UU < sceAudioChangeChannelConfig > , " sceAudioChangeChannelConfig " } ,
{ 0xB7E1D8E7 , WrapU_UUU < sceAudioChangeChannelVolume > , " sceAudioChangeChannelVolume " } ,
2012-11-23 09:33:19 +00:00
// I guess these are like the others but do sample rate conversion?
{ 0x38553111 , 0 , " sceAudioSRCChReserve " } ,
{ 0x5C37C0AE , 0 , " sceAudioSRCChRelease " } ,
{ 0xE0727056 , 0 , " sceAudioSRCOutputBlocking " } ,
// Never seen these used
2012-11-17 13:20:04 +00:00
{ 0x41efade7 , 0 , " sceAudioOneshotOutput " } ,
{ 0xB61595C0 , 0 , " sceAudioLoopbackTest " } ,
2012-11-23 09:33:19 +00:00
// Microphone interface
2012-11-17 13:20:04 +00:00
{ 0x7de61688 , 0 , " sceAudioInputInit " } ,
{ 0xE926D3FB , 0 , " sceAudioInputInitEx " } ,
2012-12-09 12:41:19 +00:00
{ 0x6d4bec68 , 0 , " sceAudioInput " } ,
{ 0x086e5895 , 0 , " sceAudioInputBlocking " } ,
{ 0xa708c6a6 , 0 , " sceAudioGetInputLength " } ,
2012-11-17 13:20:04 +00:00
{ 0xA633048E , 0 , " sceAudioPollInputEnd " } ,
{ 0x87b2e651 , 0 , " sceAudioWaitInputEnd " } ,
2012-11-01 15:19:01 +00:00
} ;
void Register_sceAudio ( )
{
2012-12-09 12:41:19 +00:00
RegisterModule ( " sceAudio " , ARRAY_SIZE ( sceAudio ) , sceAudio ) ;
2012-11-01 15:19:01 +00:00
}