I'm trying to use libAAC, but this test program plays the track too fast (really fast).
My test file is a AAC samplerate=44.10Khz, bitrate=48Kb
I'm using sceAudioOutputBlocking with (I think) correct number of samples and reserved the channel with sceAudioChReserve with the same sample number...
Can someone help me, please?
Code: Select all
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <pspaudio.h>
#include <pspthreadman.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define __ALLEGREX__
#include <aacdec.h>
#ifdef AAC_ENABLE_SBR
#define SBR_MUL 2
#else
#define SBR_MUL 1
#endif
#define SAMPLES_TO_WRITE 1024
#define PSP_VOLUME_MAX 0x8000
PSP_MODULE_INFO("libAAC test", 0, 1, 0);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
PSP_HEAP_SIZE_KB(10*1024);
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Globals:
//////////////////////////////////////////////////////////////////////////////////////////////////////
SceCtrlData input;
static int runningFlag = 1;
char fileName[50] = "ms0:/MUSIC/AAA_TEST/test.aac";
int eos = 0;
u8 *AACSourceBuffer;
u8 *readPtr;
int audio_channel = 0;
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Callbacks:
//////////////////////////////////////////////////////////////////////////////////////////////////////
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
runningFlag = 0;
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, PSP_THREAD_ATTR_USER, 0);
if(thid >= 0)
sceKernelStartThread(thid, 0, 0);
return thid;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Read tag data length:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int swapInt32BigToHost(int arg)
{
int i=0;
int checkEndian = 1;
if( 1 == *(char *)&checkEndian )
{
// Intel (little endian)
i=arg;
i=((i&0xFF000000)>>24)|((i&0x00FF0000)>>8)|((i&0x0000FF00)<<8)|((i&0x000000FF)<<24);
}
else
{
// PPC (big endian)
i=arg;
}
return i;
}
int ID3v2TagSize(const char *mp3path)
{
FILE *fp;
int size;
char sig[3];
fp = fopen(mp3path, "rb");
if (fp == NULL) return 0;
fread(sig, sizeof(char), 3, fp);
if (strncmp("ID3",sig,3) != 0) {
fclose(fp);
return 0;
}
fseek(fp, 6, SEEK_SET);
fread(&size, sizeof(unsigned int), 1, fp);
/*
* The ID3 tag size is encoded with four bytes where the first bit
* (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed
* bits are ignored, so a 257 bytes long tag is represented as $00 00 02 01.
*/
size = (unsigned int) swapInt32BigToHost((int)size);
size = ( ( (size & 0x7f000000) >> 3 ) | ( (size & 0x7f0000) >> 2 ) | ( (size & 0x7f00) >> 1 ) | (size & 0x7f) );
fclose(fp);
return size;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Decoder thread:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int decoderThread(SceSize args, void *argp){
HAACDecoder *hAACDecoder;
AACFrameInfo aacFrameInfo;
int samplesAvailable = 0;
short outputBuffer[SAMPLES_TO_WRITE * 4]__attribute__((aligned(64)));
int AAC_fd = sceIoOpen(fileName, PSP_O_RDONLY, 0777);
if (AAC_fd < 0){
pspDebugScreenPrintf("File not found!\n");
return -1;
}
double AAC_fileSize = sceIoLseek32(AAC_fd, 0, PSP_SEEK_END);
double AAC_filePos = ID3v2TagSize(fileName);
sceIoLseek32(AAC_fd, AAC_filePos, PSP_SEEK_SET);
int AACSourceBufferSize = AAC_fileSize - AAC_filePos;
AACSourceBuffer = (unsigned char *) malloc(AACSourceBufferSize + 8);
memset(AACSourceBuffer, 0, AACSourceBufferSize + 8);
if (AACSourceBuffer != 0) { // Read file in
sceIoRead(AAC_fd, AACSourceBuffer, AACSourceBufferSize);
readPtr = AACSourceBuffer;
} else {
pspDebugScreenPrintf("Error malloc!\n");
sceIoClose(AAC_fd);
return 0;
}
hAACDecoder = (HAACDecoder *) AACInitDecoder();
while (runningFlag){
samplesAvailable = 0;
memset(outputBuffer, 0, sizeof(outputBuffer));
while (samplesAvailable < SAMPLES_TO_WRITE){
unsigned long ret = AACDecode(hAACDecoder, &readPtr, &AACSourceBufferSize, &outputBuffer[samplesAvailable * 2]);
if (ret) {
pspDebugScreenPrintf("Decoder error :%li\n", ret);
eos = 1;
break;
} else {
AACGetLastFrameInfo(hAACDecoder, &aacFrameInfo);
}
samplesAvailable += aacFrameInfo.outputSamps;
}
sceAudioOutputBlocking(audio_channel, PSP_VOLUME_MAX, outputBuffer);
}
eos = 1;
free(AACSourceBuffer);
if (hAACDecoder) {
AACFreeDecoder(hAACDecoder);
hAACDecoder = NULL;
}
sceIoClose(AAC_fd);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//Main:
//////////////////////////////////////////////////////////////////////////////////////////////////////
int main(void){
pspDebugScreenInit();
SetupCallbacks();
scePowerSetCpuClockFrequency(80);
scePowerSetBusClockFrequency(54);
pspDebugScreenPrintf("File name :%s\n", fileName);
audio_channel = sceAudioChReserve(0, SAMPLES_TO_WRITE, PSP_AUDIO_FORMAT_STEREO);
if (audio_channel < 0){
pspDebugScreenPrintf("Error reserving channel!\n");
return 0;
}
//Start decoder thread:
int thid = sceKernelCreateThread("decoderThread", decoderThread, 0x18, 0x10000, PSP_THREAD_ATTR_USER, NULL);
if(thid < 0)
return 0;
sceKernelStartThread(thid, 0, NULL);
pspDebugScreenPrintf("Decoder started.\n");
while(runningFlag)
{
//Check Eof:
if (eos){
pspDebugScreenPrintf("Finished playing\n");
sceKernelDelayThread(4000000);
break;
}
sceCtrlReadBufferPositive(&input, 1);
if (input.Buttons & PSP_CTRL_TRIANGLE){
runningFlag = 0;
break;
}
sceKernelDelayThread(10000);
}
sceAudioChRelease(audio_channel);
sceKernelExitGame();
return 0;
}
Code: Select all
TARGET = libAAC_test
OBJS = main.o
#To build for custom firmware:
BUILD_PRX = 1
PSP_FW_VERSION=371
CFLAGS = -O3 -frename-registers -ffast-math -fomit-frame-pointer -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
LIBS= -laac -lpsppower -lpspaudio
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = libAAC Test
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Sakya