Files
wagic/JGE/src/JAudio.cpp
2013-12-28 12:15:52 +01:00

480 lines
12 KiB
C++

/////////////
// JAudio.c //
/////////////
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspaudiolib.h>
#include <pspaudio.h>
#include <pspsdk.h>
#include <pspaudiocodec.h>
#include <pspmpeg.h>
#include <malloc.h>
#include <string.h>
#include "../include/JGE.h"
#include "../include/JAudio.h"
#include "../include/JMP3.h"
#include "../include/JFileSystem.h"
#include "../include/decoder_prx.h"
//////////////////////////////////////////////////////////////////////////
unsigned long g_MP3CodecBuffer[65] __attribute__((aligned(64)));
short g_DecoderBuffer[SAMPLE_PER_FRAME<<1] __attribute__((aligned(64)));
short g_DecodedDataOutputBuffer[SAMPLE_PER_FRAME<<2] __attribute__((aligned(64)));
bool g_MP3DecoderOK = false;
bool g_GotEDRAM;
JMP3* g_CurrentMP3;
//////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
WAVDATA* p_currentWav[NUMBER_WAV_CHANNELS]; // 各通道当前的播放
WAVDATA currentWav[NUMBER_WAV_CHANNELS]; // 各通道当前的播放
///////////////////////////////////////////////////////////////////
void setPspVolume(int volume)
{
pspAudioSetVolume(0, volume, volume);
pspAudioSetVolume(1, volume, volume);
pspAudioSetVolume(2, volume, volume);
}
char loadWaveData(WAVDATA* p_wav, char* fileName, char memLoad) // WAVE加载, memLoad-是否加载至内磥E
{
JFileSystem* fileSystem = JFileSystem::GetInstance();
JFile* jFile = fileSystem->OpenFile(fileName);
if (!jFile)
return 0;
memset(p_wav, 0, sizeof(WAVDATA));
//SceUID fd = sceIoOpen(fileName, PSP_O_RDONLY, 0777);
char head[256];
memset(head, 0, 256);
//sceIoRead(fd, head, 20);
fileSystem->ReadFile(jFile, head, 20);
char string[8];
memset(string, 0, 8);
memcpy(string, head, 4);
if (0!=strcmp(string, "RIFF"))
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
memset(string, 0, 8);
memcpy(string, head+8, 4);
if (0!=strcmp(string, "WAVE"))
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
memset(string, 0, 8);
memcpy(string, head+12, 3);
if (0!=strcmp(string, "fmt"))
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
int fmtSize = 0;
memcpy(&fmtSize, head+16, 4);
//sceIoRead(fd, head+20, fmtSize);
fileSystem->ReadFile(jFile, head+20,fmtSize );
p_wav->headSize = 20+fmtSize;
while (1)
{
//sceIoRead(fd, head+p_wav->headSize, 4);
fileSystem->ReadFile(jFile, head+p_wav->headSize, 4);
memset(string, 0, 8);
memcpy(string, head+p_wav->headSize, 4);
p_wav->headSize += 4;
if (0!=strcmp(string, "data"))
{
//sceIoRead(fd, head+p_wav->headSize, 4);
fileSystem->ReadFile(jFile, head+p_wav->headSize, 4);
memcpy(&fmtSize, head+p_wav->headSize, 4);
p_wav->headSize += 4;
//sceIoRead(fd, head+p_wav->headSize, fmtSize);
fileSystem->ReadFile(jFile, head+p_wav->headSize, fmtSize);
p_wav->headSize += fmtSize;
}
else
{
//sceIoRead(fd, head+p_wav->headSize, 4);
fileSystem->ReadFile(jFile, head+p_wav->headSize, 4);
p_wav->headSize += 4;
break;
}
if (p_wav->headSize>191)
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
}
strcpy(p_wav->fullName, fileName);
memcpy(&p_wav->fileSize, head+4, 4);
memcpy(&p_wav->format, head+20, 2);
memcpy(&p_wav->channelCount, head+22, 2);
if (p_wav->channelCount!=1 && p_wav->channelCount!=2)
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
memcpy(&p_wav->samplePerSecond, head+24, 4);
memcpy(&p_wav->bytePerSecond, head+28, 4);
memcpy(&p_wav->bytePerSample, head+32, 2);
p_wav->bytePerSample = p_wav->bytePerSample / p_wav->channelCount;
if (p_wav->bytePerSample!=1 && p_wav->bytePerSample!=2)
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
p_wav->nSample = 44100 / p_wav->samplePerSecond;
p_wav->sizeStep = 4096 / p_wav->nSample * p_wav->channelCount / 2 * p_wav->bytePerSample / 2;
memcpy(&p_wav->soundSize, head+p_wav->headSize-4, 4);
if (memLoad)
{
if (p_wav->soundSize>4096000)
{
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
return 0;
}
p_wav->buffer = (char*)malloc(p_wav->soundSize);
memset(p_wav->buffer, 0, p_wav->soundSize);
//sceIoRead(fd, p_wav->buffer, p_wav->soundSize);
fileSystem->ReadFile(jFile, p_wav->buffer, p_wav->soundSize);
p_wav->bytePosition = 0;
p_wav->fd = -1;
//sceIoClose(fd);
fileSystem->CloseFile(jFile);
}
else
{
p_wav->bytePosition = p_wav->headSize;
//p_wav->fd = fd; // no file mode...
p_wav->fd = -1;
}
return 1;
}
///////////////////////////////////////////////////////////////////
void releaseWaveData(WAVDATA* p_wav) // WAVE释放
{
//stop channels playing this sample before doing anything
stopWaveMem(p_wav);
if (p_wav->fd==-1)
free(p_wav->buffer);
else
sceIoClose(p_wav->fd);
memset(p_wav, 0, sizeof(WAVDATA));
}
///////////////////////////////////////////////////////////////////
void audioOutCallback(int channel, void* buf, unsigned int length) // 各通道回祦E
{
WAVDATA* p_wav = NULL;
memset(buf, 0, 4096);
if (!currentWav[channel].fullName[0])
{
if (!p_currentWav[channel])
return;
p_wav = p_currentWav[channel];
if (!p_wav->fullName[0])
return;
else
{
if (p_wav->bytePosition>=p_wav->soundSize)
{
if (p_wav->flag&PW_REPLAY)
p_wav->bytePosition = 0;
else
{
p_currentWav[channel] = NULL;
return;
}
}
if (p_wav->bytePosition==0 && p_wav->delayTime)
sceKernelDelayThread(p_wav->delayTime);
}
}
else
{
p_wav = &currentWav[channel];
if (p_wav->bytePosition>=p_wav->headSize+p_wav->soundSize)
{
if (p_wav->flag&PW_REPLAY)
p_wav->bytePosition = p_wav->headSize;
else
{
releaseWaveData(&currentWav[channel]);
return;
}
if (p_wav->bytePosition==(unsigned long)p_wav->headSize && p_wav->delayTime)
sceKernelDelayThread(p_wav->delayTime);
}
}
if (p_wav->flag&PW_PAUSE)
return;
int sizeStep = p_wav->sizeStep;
int nSample = p_wav->nSample;
if (p_wav->flag&PW_FAST)
sizeStep = p_wav->sizeStep+(p_wav->sizeStep>>1);
char* tmpBuff;
char byteRead[4096];
int actualSize = 0;
if (p_wav->fd>=0)
{
if (p_wav->bytePosition+sizeStep>p_wav->headSize+p_wav->soundSize)
actualSize = p_wav->headSize+p_wav->soundSize - p_wav->bytePosition;
else
actualSize = sizeStep;
memset(byteRead, 0, 4096);
sceIoLseek(p_wav->fd, p_wav->bytePosition, PSP_SEEK_SET);
sceIoRead(p_wav->fd, byteRead, actualSize);
tmpBuff = byteRead;
}
else if (p_wav->buffer)
{
tmpBuff = p_wav->buffer + p_wav->bytePosition;
if (p_wav->bytePosition+sizeStep>p_wav->soundSize)
actualSize = p_wav->soundSize - p_wav->bytePosition;
else
actualSize = sizeStep;
}
else
return;
length = length*actualSize/sizeStep;
short val_16;
int i;
int j;
int srcPos;
for (i=0; i<(int)length; i+=nSample)
{
for (j=0; j<nSample; j++)
{
if (p_wav->bytePerSample==2)
{
if (p_wav->channelCount==2)
{
srcPos = (i<<2)/nSample;
if (p_wav->flag&PW_FAST)
srcPos = srcPos+(srcPos>>1);
memcpy((unsigned char*)buf+((i+j)<<2), tmpBuff+srcPos, 2);
memcpy((unsigned char*)buf+((i+j)<<2)+2, tmpBuff+srcPos+2, 2);
}
else if (p_wav->channelCount==1)
{
srcPos = (i<<1)/nSample;
if (p_wav->flag&PW_FAST)
srcPos = srcPos+(srcPos>>1);
memcpy((unsigned char*)buf+((i+j)<<2), tmpBuff+srcPos, 2);
memcpy((unsigned char*)buf+((i+j)<<2)+2, tmpBuff+srcPos, 2);
}
}
else if (p_wav->bytePerSample==1)
{
if (p_wav->channelCount==2)
{
srcPos = (i<<1)/nSample;
if (p_wav->flag&PW_FAST)
srcPos = srcPos+(srcPos>>1);
val_16 = 0;
memcpy(&val_16, tmpBuff+srcPos, 1);
val_16 = (val_16-128)<<8;
memcpy((unsigned char*)buf+((i+j)<<2), &val_16, 2);
val_16 = 0;
memcpy(&val_16, tmpBuff+srcPos+1, 1);
val_16 = (val_16-128)<<8;
memcpy((unsigned char*)buf+((i+j)<<2)+2, &val_16, 2);
}
else if (p_wav->channelCount==1)
{
srcPos = i/nSample;
if (p_wav->flag&PW_FAST)
srcPos = srcPos+(srcPos>>1);
val_16 = 0;
memcpy(&val_16, tmpBuff+srcPos, 1);
val_16 = (val_16-128)<<8;
memcpy((unsigned char*)buf+((i+j)<<2), &val_16, 2);
memcpy((unsigned char*)buf+((i+j)<<2)+2, &val_16, 2);
}
}
}
}
p_wav->bytePosition += sizeStep;
}
///////////////////////////////////////////////////////////////////
void audioOutCallback_0(void* buf, unsigned int length, void *userdata) {audioOutCallback(0, buf, length);}
void audioOutCallback_1(void* buf, unsigned int length, void *userdata) {audioOutCallback(1, buf, length);}
void audioOutCallback_2(void* buf, unsigned int length, void *userdata) {audioOutCallback(2, buf, length);}
//void audioOutCallback_3(void* buf, unsigned int length, void *userdata) {audioOutCallback(3, buf, length);}
///////////////////////////////////////////////////////////////////
char playWaveFile(int channel, char* fullName, unsigned long flag) // 播放WAVE文件
{
stopWaveMem(channel);
if (currentWav[channel].fullName[0])
releaseWaveData(&currentWav[channel]);
if (!loadWaveData(&currentWav[channel], fullName, 0))
return 0;
currentWav[channel].flag = flag;
return 1;
// ...
}
///////////////////////////////////////////////////////////////////
void stopWaveFile(int channel) // 停止WAVE文件
{
if (currentWav[channel].fullName[0])
releaseWaveData(&currentWav[channel]);
}
///////////////////////////////////////////////////////////////////
int playWaveMem(WAVDATA* p_wav, unsigned long flag) // 播放WAVE
{
int i;
for (i=0;i<NUMBER_WAV_CHANNELS;i++)
{
if (p_currentWav[i] == NULL)
{
//stopWaveFile(channel);
if (!p_wav)
return -1;
if (!p_wav->soundSize)
return -1;
p_currentWav[i] = p_wav;
p_currentWav[i]->flag = flag;
p_currentWav[i]->bytePosition = 0;
return i;
}
}
return -1;
}
void stopWaveMem (WAVDATA * pWav)
{
for (int i = 0; i < NUMBER_WAV_CHANNELS; ++i)
{
if (p_currentWav[i] == pWav)
stopWaveMem(i);
}
}
///////////////////////////////////////////////////////////////////
void stopWaveMem(int channel) // 停止WAVE
{
p_currentWav[channel] = NULL;
}
///////////////////////////////////////////////////////////////////
void setChannelFlag(int channel, int flag) // 设置播放属性
{
WAVDATA* p_wav = NULL;
if (!currentWav[channel].fullName[0])
{
if (!p_currentWav[channel])
return;
p_wav = p_currentWav[channel];
if (!p_wav->fullName[0])
return;
}
else
p_wav = &currentWav[channel];
p_wav->flag = flag;
}
///////////////////////////////////////////////////////////////////
void audioInit() // 初始化
{
int i;
for (i=0; i<NUMBER_WAV_CHANNELS; i++)
{
memset(&currentWav[i], 0, sizeof(WAVDATA));
p_currentWav[i] = NULL;
}
JMP3::init();
pspAudioInit();
pspAudioSetChannelCallback(0, audioOutCallback_0, NULL);
pspAudioSetChannelCallback(1, audioOutCallback_1, NULL);
pspAudioSetChannelCallback(2, audioOutCallback_2, NULL);
}
void audioDestroy()
{
pspAudioEndPre();
sceKernelDelayThread(100000);
pspAudioEnd();
}
int mp3thread = 0;
//////////////////////////////////////////////////////////////////////////
void PlayMP3(JMP3 *mp3, bool looping)
{
if (mp3thread) StopMP3();
JMP3::mInstance = mp3;
mp3->setLoop(looping);
mp3->play();
mp3thread = sceKernelCreateThread("decodeThread2", decodeThread2, 0x12, 0xFA0, 0, 0);
printf("thread id : %i\n", mp3thread);
sceKernelStartThread(mp3thread, 0, NULL);
}
//////////////////////////////////////////////////////////////////////////
void StopMP3()
{
printf("stop 1\n");
JMP3 * mp3 = JMP3::mInstance;
printf("stop 2\n");
if (mp3){
printf("stop 3\n");
mp3->pause();
printf("stop 4\n");
sceKernelWaitThreadEnd(mp3thread, NULL);
printf("stop 5\n");
sceKernelDeleteThread(mp3thread);
printf("stop 6\n");
mp3->unload();
printf("stop 7\n");
JMP3::mInstance = NULL;
mp3thread = 0;
}
printf("stop 8\n");
}
//////////////////////////////////////////////////////////////////////////
void ResumeMP3(JMP3 * mp3)
{
mp3->play();
}
int decodeThread2(SceSize args, void *argp){
JMP3 * mp3 = NULL;
while((mp3 = JMP3::mInstance) && !mp3->m_paused){
mp3->update();
//sceKernelDelayThread(10000);
}
return 0;
}