thug/Code/Gel/Music/Ngps/Bgm/bgm_play.c

798 lines
20 KiB
C
Raw Normal View History

2016-02-13 21:39:12 +00:00
#include <stdio.h>
#include <sys/file.h>
#include <kernel.h>
#include <string.h>
#include <libsd.h>
#include <libcdvd.h>
#include "bgm_i.h"
#define DEBUGGING_PLEASE 0
#if DEBUGGING_PLEASE
#define Dbg_Printf(A...) printf(##A)
#else
#define Dbg_Printf(A...)
#endif
// wav format ------------------------
#define RIFF_HEADER_SIZE 44
typedef struct {
unsigned char chunkID[4];
unsigned int chunkSize;
unsigned short* data;
} DATAHeader;
typedef struct {
unsigned char chunkID[4];
unsigned int chunkSize;
unsigned short waveFmtType;
unsigned short channel;
unsigned int samplesPerSec;
unsigned int bytesPerSec;
unsigned short blockSize;
unsigned short bitsPerSample;
} FMTHeader;
typedef struct {
unsigned char chunkID[4];
unsigned int chunkSize;
unsigned char formType[4];
FMTHeader fmtHdr;
DATAHeader dataHdr;
} RIFFHeader;
//------------------------------------
typedef struct {
unsigned int size;
// unsigned int offset;
unsigned int pos;
} BGM_WAVE;
BGM_WAVE gWave[2];
int gMemInitializedForCD = 0;
short gBgmPause[2] = { 0, 0 };
short gBgmPreload[ 2 ] = { 0, 0 };
char gFileFromCD[ 2 ] = { 0, 0 };
char gBgmVolumeSet[2] = { 0, 0 };
volatile char gFileOpened[2] = { 0, 0 };
volatile char gBgmIntr[2] = { 0, 0 };
int gThid = 0;
int gSem = 0;
int gFd[2];
int gBuffRaw[2];
int gBuffSpu[2] = {0, 0};
int gRPacketSize[2];
int gSPacketSize[2];
int gAllockedSize[2];
int gBgmVolume[2];
int gBgmMode[2] = { BGM_MODE_REPEAT_OFF, BGM_MODE_REPEAT_OFF };
int gBgmStereoMode[ 2 ] = { 0, 0 };
#define MAX_FILENAME_LENGTH 50
char gFilename[ 2 ][ MAX_FILENAME_LENGTH ];
// Larger buffers will prevent skipping when loading in the background...
// The more streams, the larger the buffers have to be.
// Reading from the CDVD will be faster than debug stations from the host over the network,
// so don't freak if you notice corruption on a dev system w/o CD.
#define SECTOR_SIZE 2048
#define NUM_SECTORS_PER_READ 2
#define BUFFER_SIZE_FOR_HOST_FILE ( 2048 * 132 ) // multiple of 6
#define BUFFER_SIZE_FOR_CD_FILE ( SECTOR_SIZE * NUM_SECTORS_PER_READ * 6 )
#define RING_BUFFER_NUM_SECTORS 48
#define RING_BUFFER_ALLIGNMENT 64
#define RING_BUFFER_NUM_PARTITIONS 3
unsigned char gRingBuffer[ 2 ][ RING_BUFFER_NUM_SECTORS * 2048 ] __attribute__((aligned ( RING_BUFFER_ALLIGNMENT )));
unsigned char gCDBuffSpu[ 2 ][ BUFFER_SIZE_FOR_CD_FILE ]__attribute__((aligned ( 64 )));
int _BgmPlay( int status );
void _BgmRaw2Spu(u_long *src, u_long *dst, u_long block_count );
void _BgmRaw2SpuMono(u_long *src, u_long *dst, u_long block_count );
int BgmPreLoad( int ch, int status );
void SetStereoOn( int ch, int stereo );
static int IntFunc0( void* common )
{
gBgmIntr[0] = 1;
iSignalSema( gSem );
return 1; //-- Required for re-enabling interrupts
}
static int IntFunc1( void* common )
{
gBgmIntr[1] = 1;
iSignalSema( gSem );
return 1; //-- Required for re-enabling interrupts
}
static int makeMyThread( void )
{
struct ThreadParam param;
int thid;
param.attr = TH_C;
param.entry = _BgmPlay;
param.initPriority = BASE_priority-3;
param.stackSize = 0x800;
param.option = 0;
/* Create thread */
thid = CreateThread(&param);
return thid;
}
static int makeMySem( void )
{
struct SemaParam sem;
sem.initCount = 0;
sem.maxCount = 1;
sem.attr = AT_THFIFO;
/* Create semaphore. */
return CreateSema(&sem);
}
int BgmRaw2Spu( int ch, int which )
{
if ( gBgmStereoMode[ ch ] )
{
_BgmRaw2Spu( (u_long *)(gBuffRaw[ch]+ (gRPacketSize[ch])*which)
, (u_long *)(gBuffSpu[ch] + (gSPacketSize[ch])*which)
, gSPacketSize[ch]/1024 );
}
else
{
_BgmRaw2SpuMono ((u_long *)(gBuffRaw [ch] + (gRPacketSize [ch]) * which),
(u_long *)(gBuffSpu [ch] + (gSPacketSize [ch]) * which),
gSPacketSize [ch] / 1024);
}
return 0;
}
// returns zero if no longer playing...
int BgmSetVolumeDirect( int ch, unsigned int vol )
{
sceSdSetParam( (ch)|SD_P_BVOLR, vol>>16 );
sceSdSetParam( (ch)|SD_P_BVOLL, vol&0xFFFF);
return ( gBgmMode[ch] & ~BGM_MASK_STATUS );
}
void BgmSdInit(int ch, int status )
{
// This is already called from the soundFX module.
//sceSdInit(0);
return;
}
int BgmInit( int ch, int useCD )
{
if( gSem == 0 ){
gSem = makeMySem();
}
if( gThid == 0 ){
gThid = makeMyThread();
Dbg_Printf("PCM Audio Streamer: create thread ID= %d, ", gThid );
/* Activate thread */
StartThread( gThid, (u_long)NULL );
}
if ( !gBuffSpu[ ch ] )
{
gAllockedSize[ch] = useCD ? BUFFER_SIZE_FOR_CD_FILE : BUFFER_SIZE_FOR_HOST_FILE;
if ( useCD )
{
gBuffSpu[ ch ] = ( int )gCDBuffSpu[ ch ]; //(int)AllocSysMemory( 0, gAllockedSize[ ch ], NULL );
}
else
{
gBuffSpu[ ch ] = ( int )AllocSysMemory( 0, gAllockedSize[ ch ], NULL );
}
Dbg_Printf(" PCM spu buffer mem: 0x%x - 0x%x\n", gBuffSpu[ch], gBuffSpu[ch]+gAllockedSize[ ch ] );
}
// the memory should work for mono or stereo 44k files ( raw buffer always the same... )
gRPacketSize[ ch ] = gAllockedSize[ ch ] / 6;
gBuffRaw[ ch ] = ( int )( gBuffSpu[ ch ] + ( gRPacketSize[ ch ] * 4 ) );
gMemInitializedForCD = useCD;
return gThid;
}
void BgmQuit(int ch, int status )
{
if ( ( gBuffSpu[ ch ] ) && ( gBuffSpu[ ch ] != ( int ) gCDBuffSpu ) )
FreeSysMemory( (void*)gBuffSpu[ch] );
gBuffSpu[ch] = 0;
//-- Frees resources unless another channel is used.
if( gBuffSpu[1-ch] == 0 ){
if (gThid != 0) TerminateThread( gThid );
if (gSem != 0) DeleteSema( gSem );
if (gThid != 0) DeleteThread( gThid );
gThid = 0;
gSem = 0;
}
return;
}
/*
void WaitForCDReady( char *description )
{
printf( "wait %s", description );
while( SCECdComplete != sceCdDiskReady( 1 ) )
{
printf( "." );
}
printf( "\n" );
}*/
#define NUM_BYTES_TO_CLEAR 512 // must be divisible by 4!!!
int BgmOpen( int data, char* filename )
{
// unsigned int channel;
RIFFHeader wavHdr;
int offset;
int *addr;
int i;
int ch = data & 1;
int stereo = data & WAV_STEREO_BIT;
SetStereoOn( ch, stereo );
for ( i = 0; i < 2; i++ )
{
if ( gFileOpened[ i ] )
{
printf( "%s: Failed: Audio stream already running: %s\n", filename, gFilename[ i ] );
// Dbg_Printf( "File already opened on that channel...\n" );
return -1;
}
}
printf("pcm filename %s\n", filename );
if ( !strncmp( filename, "host", 4 ) )
{
if ( gMemInitializedForCD )
{
printf( "Loading file from host when mem configured for CD... SOUND QUALITY WILL SUCK.\n" );
printf( "If calling ezBGM_INIT with useCD (2nd param), send CDROM0 in filename...\n" );
}
// load the file from the dev system...
if (( gFd[ch] = open ( filename, O_RDONLY)) < 0)
{
ERROR(("file open failed. %s \n", filename));
return -1;
}
if ( read (gFd[ch], (unsigned char*)(&wavHdr)
,RIFF_HEADER_SIZE ) != RIFF_HEADER_SIZE ) {
ERROR(("file read failed. %s \n", filename));
return -1;
}
if ( wavHdr.fmtHdr.channel == 2 )
{
if ( !stereo )
printf( "WARNING: Playing stereo sound %s in mono mode.\n", filename );
}
else if ( stereo )
{
printf( "WARNING: Playing mono sound %s in stereo mode.\n", filename );
}
gWave[ch].size = wavHdr.dataHdr.chunkSize;
gWave[ch].pos = 0;
//--- Seek to start of data
offset = (unsigned int)&(wavHdr.dataHdr.data) -(unsigned int)&wavHdr;
lseek( gFd[ ch ], offset , SEEK_SET );
gFileFromCD[ ch ] = 0;
gFileOpened[ ch ] = 1;
gBgmPreload[ ch ] = 3;
}
else
{
sceCdlFILE fp;
sceCdRMode mode;
int retVal;
unsigned int stringLength;
unsigned int lsn;
int foundCDData = 0;
int byteIndex;
// open a stream and load from CD...
// 1st arg: size in num sectors ( actual size / 2048 ).
// WaitForCDReady( "st init" );
// sceCdDiskReady( 0 );
sceCdStInit( RING_BUFFER_NUM_SECTORS, RING_BUFFER_NUM_PARTITIONS, ( u_int )( gRingBuffer[ ch ] ) ); //+ ( RING_BUFFER_ALLIGNMENT - 1 ) ) );
// printf( "wait for ready." );
// sceCdDiskReady( 0 );
// WaitForCDReady( "init" );
// printf( "cdSearchFile\n" );
stringLength = strlen( filename );
if ( filename[ stringLength + 1 ] == '@' )
{
foundCDData = 1;
lsn = 0;
for ( byteIndex = 0; byteIndex < 4; byteIndex++ )
{
lsn |= ( ( ( unsigned int )( filename[ stringLength + 2 + byteIndex ] ) ) & 255 ) << ( 8 * byteIndex );
}
}
if ( !foundCDData )
{
if ( !( retVal = sceCdSearchFile( &fp, filename ) ) )
{
ERROR(("cd filesearch failed %d. file %s \n", retVal, filename));
return -1;
}
lsn = fp.lsn;
}
// WaitForCDReady( "find" );
// sceCdDiskReady( 0 );
mode.trycount = 0;
mode.spindlctrl = SCECdSpinNom;
mode.datapattern = SCECdSecS2048;
sceCdStStart( lsn, &mode );
gFileFromCD[ ch ] = 1;
gBgmPreload[ ch ] = 3;
gFileOpened[ ch ] = 1;
gWave[ ch ].pos = 0;
gWave[ ch ].size = gRPacketSize[ ch ] * 4;
}
// printf("wave size %d offset %d\n", gWave[ch].size, gWave[ch].offset );
BgmSetVolumeDirect( ch, 0 );
strncpy( gFilename[ ch ], filename, MAX_FILENAME_LENGTH );
// clear out the end of the second half of the last buffer...
addr = ( int * )( gBuffRaw[ ch ] + ( gRPacketSize[ ch ] ) + ( gRPacketSize[ ch ] >> 1 ) );
for ( i = 0; i < ( ( gRPacketSize[ ch ] >> 1 ) >> 2 ); i++ )
{
*( addr++ ) = 0;
}
if( ch == 0 )
{
sceSdSetTransCallback( ch, IntFunc0 );
}
else
{
sceSdSetTransCallback( ch, IntFunc1 );
}
return ( gWave[ ch ].size );
}
void _BgmClose(int ch, int status)
{
if ( !gFileOpened[ ch ] )
{
PRINTF(("Calling BgmClose when no file opened on that channel...\n"));
return;
}
Dbg_Printf( "_BgmClose\n" );
if ( gFileFromCD[ ch ] )
{
sceCdStStop( );
}
else
{
close( gFd[ch] );
//FreeSysMemory( ( void* )gBuffSpu[ ch ] );
//gBuffSpu[ ch ] = 0;
}
gFileOpened[ ch ] = 0;
return;
}
void BgmStart(int ch, int status )
{
int retVal;
if ( !gFileOpened[ ch ] )
{
printf( "trying to start track not loaded.\n" );
return;
}
Dbg_Printf( "starting block trans from bgm start/unpause\n" );
if ( gBgmPause[ ch ] )
{
Dbg_Printf( "Starting music on channel where pause is requested...\n" );
gBgmPause[ ch ] = 0;
}
while( -1 == sceSdBlockTrans( ch, SD_TRANS_MODE_WRITE|SD_BLOCK_LOOP, (u_char*)gBuffSpu[ch], (gSPacketSize[ch]*2) ) )
{
for ( retVal = 0; retVal < 10000; retVal++ )
;
Dbg_Printf( "failed to start loop.\n" );
}
if ( !( gBgmPreload[ ch ] ) )
{
BgmSetVolumeDirect(ch, gBgmVolume[ch]);
}
gBgmMode[ch] &= BGM_MASK_STATUS;
gBgmMode[ch] |= BGM_MODE_RUNNING;
return;
}
void BgmCloseNoWait( int ch, int status )
{
if ( !gFileOpened[ ch ] )
{
PRINTF(("Calling BgmClose when no file opened on that channel...\n"));
return;
}
if ( gBgmPause[ ch ] )
{
printf( "stopping music when pause is requested..." );
return;
}
// if the pause has already stopped the callback, it's safe to unload now:
if ( gBgmMode[ ch ] & BGM_MODE_PAUSE )
{
// callback isn't happening right now... can terminate with no worries here:
Dbg_Printf( "unpausing from BgmClose\n" );
gBgmMode[ch] &= BGM_MASK_STATUS; // Switch to IDLE mode
_BgmClose( ch, status );
Dbg_Printf( "calling _BgmClose from BgmClose\n" );
return;
}
gBgmMode[ch] &= BGM_MASK_STATUS;
gBgmMode[ch] |= BGM_MODE_TERMINATE;
}
void BgmClose( int ch, int status )
{
int i;
BgmCloseNoWait( ch, status );
printf( "PCM close" );
while ( ( gBgmMode[ ch ] & BGM_MODE_TERMINATE ) )
{
for ( i = 0; i < 20000; i++ )
;
printf( "." );
}
printf( "\n" );
}
int BgmPreLoad( int ch, int status )
{
if ( ( status == 666 ) || ( ( gWave[ ch ].size - gWave[ ch ].pos ) < gRPacketSize[ ch ] * 4 ) )
{
int i;
int *addr;
Dbg_Printf( "preloading at end of song. zero buffers.\n" );
// we're at the end of the song... fill up read buffers with zero,
// and convert...
addr = ( int * )( gBuffRaw[ ch ] );
for ( i = 0; i < ( ( gRPacketSize[ ch ] * 2 ) >> 2 ); i++ )
{
*( addr++ ) = 0;
}
// fill up the spu with both buffers...
BgmRaw2Spu( ch, 0 );
BgmRaw2Spu( ch, 1 );
return ( 0 );
}
// it's still in preload mode... no need to preload ourselves...
if ( gBgmPreload[ ch ] == 3 )
return ( 0 );
if ( gFileFromCD[ ch ] )
{
unsigned int err;
sceCdStRead( NUM_SECTORS_PER_READ * 2, ( u_int * )gBuffRaw[ ch ], STMBLK, &err );
if ( err )
{
printf( "PCM A Disk error code 0x%08x\n", err );
}
// fill up the spu with both buffers...
BgmRaw2Spu( ch, 0 );
BgmRaw2Spu( ch, 1 );
// fill up the buffers again...
sceCdStRead( NUM_SECTORS_PER_READ * 2, ( u_int * )gBuffRaw[ ch ], STMBLK, &err );
if ( err )
{
printf( "PCM B Disk error code 0x%08x\n", err );
}
gWave[ ch ].pos += gRPacketSize[ ch ] * 2;
return 0;
}
// reading from a file...
if ( read (gFd[ch], (unsigned char*)(gBuffRaw[ch])
, gRPacketSize[ch]*2 ) != gRPacketSize[ch]*2 ) {
ERROR (("BgmPreLoad: read failed \n")); return -1;
}
BgmRaw2Spu( ch, 0 );
BgmRaw2Spu( ch, 1 );
if ( read (gFd[ch], (unsigned char*)(gBuffRaw[ch])
, (gRPacketSize[ch]*2) ) != gRPacketSize[ch]*2) {
ERROR (("BgmPreLoad: read failed \n")); return -1;
}
gWave[ch].pos += gRPacketSize[ch]*4;
return 0;
}
void _BgmPause(int ch, int status)
{
Dbg_Printf( "stopping spu block trans in _BgmPause\n" );
sceSdBlockTrans( ch, SD_TRANS_MODE_STOP, NULL, 0 );
gBgmMode[ch] &= BGM_MASK_STATUS; // Switch to PAUSE mode
gBgmMode[ch] |= BGM_MODE_PAUSE;
return;
}
void _BgmStopAndUnload(int ch, int status)
{
Dbg_Printf( "stopping block trans from _BgmStopAndUnload\n" );
sceSdBlockTrans( ch, SD_TRANS_MODE_STOP, NULL, 0 );
gBgmMode[ch] &= BGM_MASK_STATUS; // Switch to IDLE mode
Dbg_Printf( "bgm close from _BgmStopAndUnload\n" );
_BgmClose( ch, status );
return;
}
// should be fucking called "BgmPause"
void BgmStop( int ch, unsigned int vol )
{
int i;
if ( gBgmMode[ ch ] & BGM_MODE_TERMINATE )
{
Dbg_Printf( "trying to pause PCM when stopped.\n" );
return;
}
if ( !gBgmMode[ ch ] & BGM_MODE_RUNNING )
{
Dbg_Printf( "trying to pause PCM when not running.\n" );
return;
}
gBgmPause[ch] = 1;
printf( "waiting for pause" );
while ( !( gBgmMode[ ch ] & BGM_MODE_PAUSE ) )
{
for ( i = 0; i < 10000; i++ )
;
printf( "." );
}
printf( "\n" );
// don't set the flag until the callback has paused it:
// gBgmMode[ch] &= BGM_MASK_STATUS;
// gBgmMode[ch] |= BGM_MODE_PAUSE;
return;
}
int BgmSetVolume( int ch, unsigned int vol )
{
gBgmVolumeSet[ch] = 1;
gBgmVolume[ch] = vol;
return ( gBgmMode[ch] & ~BGM_MASK_STATUS );
}
unsigned int BgmGetMode( int ch, int status )
{
return gBgmMode[ch];
}
void BgmSeek( int ch, unsigned int value )
{
// lseek(gFd[ch], gWave[ch].offset+value, SEEK_SET );
// gWave[ch].pos = value;
printf( "seek not supported\n" );
return;
}
void SetStereoOn( int ch, int stereo )
{
if ( stereo )
{
gSPacketSize[ ch ] = gAllockedSize[ ch ] / 6;
gBgmStereoMode[ ch ] = 1;
}
else
{
gSPacketSize[ ch ] = gAllockedSize [ ch ] / 3;
gBgmStereoMode[ ch ] = 0;
}
}
void PreloadFile( int which, int ch )
{
switch ( gBgmPreload[ ch ] )
{
case ( 3 ):
if ( gFileFromCD[ ch ] )
{
RIFFHeader *pWavHdr;
int i;
int offset;
unsigned char *pData;
pWavHdr = ( RIFFHeader * )( gBuffRaw[ ch ]+gRPacketSize[ch]*which );
if ( pWavHdr->dataHdr.chunkSize < gWave[ ch ].size )
{
printf( "BIG WARNING: Cd audio file currently playing is TOO SMALL!\n" );
}
if ( pWavHdr->fmtHdr.channel == 2 )
{
if ( !gBgmStereoMode[ ch ] )
printf( "WARNING: Playing stereo sound %s in mono mode.\n", gFilename[ ch ] );
}
else if ( gBgmStereoMode[ ch ] )
{
printf( "WARNING: Playing mono sound %s in stereo mode.\n", gFilename[ ch ] );
}
SetStereoOn( ch, pWavHdr->fmtHdr.channel == 2 );
gWave[ch].size = pWavHdr->dataHdr.chunkSize;
//gWave[ch].offset = (unsigned int)&( pWavHdr->dataHdr.data ) - ( unsigned int )pWavHdr;
offset = (unsigned int)&( pWavHdr->dataHdr.data ) - ( unsigned int )pWavHdr;
// clear out the area where the header is... don't want some loud obnoxious sounds...
pData = ( unsigned char * )( gBuffRaw[ ch ]+gRPacketSize[ch]*which );
if ( offset > gRPacketSize[ ch ] )
offset = gRPacketSize[ ch ]; // don't fuck up memory if some strange read happened...
for ( i = 0; i < offset; i++ )
{
pData[ i ] = 0;
}
}
break;
case ( 2 ):
break;
case ( 1 ):
// turn the volume back up, the spooler is at the beginning of
// the good SPU buffer...
BgmSetVolume( ch, gBgmVolume[ch] );
break;
default:
printf( "unknown preload state... fire Matt.\n" );
break;
}
--gBgmPreload[ ch ];
}
int _BgmPlay( int status )
{
int i, ch, read_size, which;
int *addr, remain;
Dbg_Printf( "entering _BgmPlay\n" );
while ( 1 )
{
//-- Wait for playing of buffer to finish
WaitSema(gSem);
//-- Which channel is the interrupt from?
if( (gBgmIntr[0] == 1) && ( ch != 0 ) ) ch = 0;
else if( (gBgmIntr[1] == 1) && ( ch != 1 ) ) ch = 1;
else if( gBgmIntr[0] == 1 ) ch = 0;
else if( gBgmIntr[1] == 1 ) ch = 1;
else continue;
gBgmIntr[ch] = 0;
which = 1 - (sceSdBlockTransStatus( ch, 0 )>>24);
//--- Stopped due to end of data (no looping)
if( ( gBgmMode[ ch ] & BGM_MODE_TERMINATE ) != 0 )
{
WaitSema( gSem ); // Wait until another interrupt is received
_BgmStopAndUnload( ch, 0 );
BgmSetVolumeDirect( ch, 0x0 );
continue;
}
//--- Volume change event
if ( ( gBgmVolumeSet[ ch ] == 1 ) && ( !gBgmPreload[ ch ] ) )
{
BgmSetVolumeDirect( ch, gBgmVolume[ch] );
gBgmVolumeSet[ch] = 0;
}
//--- Convert buffer
BgmRaw2Spu( ch, which );
//--- File READ for buffer
remain = gWave[ ch ].size - gWave[ ch ].pos;
if ( remain > gRPacketSize[ch] )
{
if ( gFileFromCD[ ch ] )
{
//--- Not end of data
unsigned int err;
sceCdStRead( NUM_SECTORS_PER_READ, ( u_int * )( gBuffRaw[ ch ]+gRPacketSize[ch]*which ), STMBLK, &err );
if ( err )
{
printf( "PCM C Disk error code 0x%08x\n", err );
}
read_size = gRPacketSize[ ch ];
}
else
{
read_size = read (gFd[ch], (unsigned char*)(gBuffRaw[ch]+gRPacketSize[ch]*which), gRPacketSize[ch] );
}
if ( read_size < gRPacketSize[ch] )
continue; //retry
if ( gBgmPreload[ ch ] )
{
PreloadFile( which, ch );
}
gWave[ch].pos += read_size;
}
else //--- End of data
{
if ( gFileFromCD[ ch ] )
{
//--- Not end of data
unsigned int err;
sceCdStRead( NUM_SECTORS_PER_READ, ( u_int * )( gBuffRaw[ ch ]+gRPacketSize[ch]*which ), STMBLK, &err );
if ( err )
{
printf( "PCM C Disk error code 0x%08x\n", err );
}
read_size = gRPacketSize[ ch ];
}
else
{
read_size = read (gFd[ch], (unsigned char*)(gBuffRaw[ch]+gRPacketSize[ch]*which), remain );
}
if( read_size < remain ) continue; //retry
PRINTF(("end of PCM track - ch %d\n", ch));
addr = ( int * )( gBuffRaw[ ch ] + ( gRPacketSize[ ch ] * which ) + remain );
for( i = 0; i < ((gRPacketSize[ch]-remain)>>2); i++ )
{
*(addr++) = 0;
}
gBgmMode[ch] &= BGM_MASK_STATUS;
gBgmMode[ch] |= BGM_MODE_TERMINATE;
}
//-- Stop event
if( (gBgmPause[ch] == 1) )
{
//printf( "_BgmPlay :: pause\n" );
_BgmPause( ch, 0 );
BgmSetVolumeDirect(ch, 0x0);
gBgmPause[ch] = 0;
}
}
return 0;
}
/* ----------------------------------------------------------------
* End on File
* ---------------------------------------------------------------- */
/* This file ends here, DON'T ADD STUFF AFTER THIS */
// Ha ha I added some stuff... FUCK YOU SONY!