Finished audio player. Added OGG playback.

This commit is contained in:
TheFloW 2016-09-12 15:49:51 +02:00
parent 45dfc6093d
commit da2e11f0a1
32 changed files with 1150 additions and 141 deletions

View File

@ -2,20 +2,19 @@ TITLE_ID = VITASHELL
TARGET = VitaShell
OBJS = main.o init.o io_process.o package_installer.o network_update.o context_menu.o archive.o photo.o audioplayer.o file.o text.o hex.o sfo.o \
uncommon_dialog.o message_dialog.o ime_dialog.o config.o theme.o language.o utils.o sha1.o \
minizip/unzip.o minizip/ioapi.o bm.o audio/vita_audio.o audio/player.o audio/id3.o audio/mp3player.o audio/mp3xing.o \
minizip/unzip.o minizip/ioapi.o bm.o audio/vita_audio.o audio/player.o audio/id3.o audio/oggplayer.o audio/mp3player.o audio/mp3xing.o \
libmad/bit.o libmad/decoder.o libmad/fixed.o libmad/frame.o \
libmad/huffman.o libmad/layer12.o libmad/layer3.o \
libmad/stream.o libmad/synth.o libmad/timer.o
RESOURCES_PNG = resources/folder_icon.png resources/file_icon.png resources/archive_icon.png resources/image_icon.png \
resources/audio_icon.png resources/sfo_icon.png resources/text_icon.png\
resources/ftp.png resources/battery.png resources/battery_bar_green.png resources/battery_bar_red.png \
resources/battery_bar_charge.png
RESOURCES_TXT = resources/theme.txt resources/colors.txt resources/english_us.txt resources/changeinfo.txt
RESOURCES_BIN = resources/updater_eboot.bin resources/updater_param.bin
RESOURCES = resources
RESOURCES_PNG := $(foreach dir,$(RESOURCES), $(wildcard $(dir)/*.png))
RESOURCES_TXT := $(foreach dir,$(RESOURCES), $(wildcard $(dir)/*.txt))
RESOURCES_BIN := $(foreach dir,$(RESOURCES), $(wildcard $(dir)/*.bin))
OBJS += $(RESOURCES_PNG:.png=.o) $(RESOURCES_TXT:.txt=.o) $(RESOURCES_BIN:.bin=.o)
LIBS = -lftpvita -lvita2d -lpng -ljpeg -lz -lm -lc \
LIBS = -lvorbisfile -logg -lvorbis -lftpvita -lvita2d -lpng -ljpeg -lz -lm -lc \
-lSceAppMgr_stub -lSceAppUtil_stub -lSceCommonDialog_stub \
-lSceCtrl_stub -lSceDisplay_stub -lSceGxm_stub -lSceIme_stub \
-lSceHttp_stub -lSceKernel_stub -lSceNet_stub -lSceNetCtl_stub \

View File

@ -184,6 +184,7 @@ Be sure you pull request your customized design or language file there.
* vitasdk: https://github.com/vitasdk
* vita2dlib: https://github.com/xerpi/vita2dlib
* ftpvitalib https://github.com/xerpi/ftpvitalib
* EasyRPG libraries: https://ci.easyrpg.org/view/Toolchains/job/toolchain-vita/
### Credits ###
* Team Molecule for HENkaku

View File

@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <psp2/io/fcntl.h>
#include <psp2/kernel/threadmgr.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -26,7 +27,6 @@
#include "id3.h"
#include "mp3xing.h"
#include "player.h"
#include "vita_audio.h"
#include "mp3player.h"
#define FALSE 0
@ -152,7 +152,7 @@ int fillFileBuffer() {
// Read into the rest of the file buffer.
unsigned char* bufferPos = fileBuffer + bytesToKeep;
while (bytesToFill > 0){
unsigned int bytesRead = sceIoRead(MP3_fd, bufferPos, bytesToFill);
int bytesRead = sceIoRead(MP3_fd, bufferPos, bytesToFill);
if (bytesRead == 0x80010013) {
MP3_suspend();
@ -242,7 +242,14 @@ static void MP3Callback(void *buffer, unsigned int samplesToWrite, void *pdata){
//Check for playing speed:
if (MP3_playingSpeed){
if (sceIoLseek32(MP3_fd, 2 * INPUT_BUFFER_SIZE * MP3_playingSpeed, SCE_SEEK_CUR) != MP3_filePos){
int res = sceIoLseek32(MP3_fd, 2 * INPUT_BUFFER_SIZE * MP3_playingSpeed, SCE_SEEK_CUR);
if (res == 0x80010013) {
MP3_suspend();
MP3_resume();
res = sceIoLseek32(MP3_fd, 2 * INPUT_BUFFER_SIZE * MP3_playingSpeed, SCE_SEEK_CUR);
}
if (res != MP3_filePos){
MP3_filePos += 2 * INPUT_BUFFER_SIZE * MP3_playingSpeed;
mad_timer_set(&Timer, (int)((float)MP3_info.length / 100.0 * MP3_GetPercentage()), 1, 1);
}else
@ -580,6 +587,9 @@ int MP3_Load(char *filename){
return OPENING_OK;
}
int MP3_IsPlaying() {
return MP3_isPlaying;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This function initialises for playing, and starts
@ -637,7 +647,7 @@ float MP3_GetPercentage(){
float perc = 0.0f;
if (fileSize > 0){
perc = ((float)MP3_filePos - (float)tagsize) / ((float)fileSize - (float)tagsize) * 100.0;
perc = ((float)MP3_filePos) / ((float)fileSize - (float)tagsize) * 100.0;
if (perc > 100)
perc = 100;
}

View File

@ -15,12 +15,13 @@
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <mad.h>
#include "../libmad/mad.h"
extern int MP3_defaultCPUClock;
//private functions
void MP3_Init(int channel);
int MP3_IsPlaying();
int MP3_Play();
void MP3_Pause();
int MP3_Stop();

View File

@ -18,7 +18,7 @@
#ifndef __mp3xing_h
#define __mp3xing_h (1)
#include <mad.h>
#include "../libmad/mad.h"
#define XING_BUFFER_SIZE 300
#define XING_GUID (unsigned char [4]) \

536
audio/oggplayer.c Normal file
View File

@ -0,0 +1,536 @@
// LightMP3
// Copyright (C) 2007 Sakya
// sakya_tg@yahoo.it
//
// 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
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <psp2/io/fcntl.h>
#include <psp2/kernel/threadmgr.h>
#include <string.h>
//#include "tremor/ivorbiscodec.h" //libtremor
//#include "tremor/ivorbisfile.h" //libtremor
#include <vorbis/codec.h> //ogg-vorbis
#include <vorbis/vorbisfile.h> //ogg-vorbis
#include "player.h"
#include "oggplayer.h"
/////////////////////////////////////////////////////////////////////////////////////////
//Globals
/////////////////////////////////////////////////////////////////////////////////////////
static int OGG_audio_channel;
static int OGG_channels = 0;
static char OGG_fileName[264];
static int OGG_file = -1;
static OggVorbis_File OGG_VorbisFile;
static int OGG_eos = 0;
static struct fileInfo OGG_info;
static int OGG_isPlaying = 0;
static unsigned int OGG_volume_boost = 0.0;
static double OGG_milliSeconds = 0.0;
static int OGG_playingSpeed = 0; // 0 = normal
static int OGG_playingDelta = 0;
static int outputInProgress = 0;
static long OGG_suspendPosition = -1;
static long OGG_suspendIsPlaying = 0;
int OGG_defaultCPUClock = 50;
static short OGG_mixBuffer[VITA_NUM_AUDIO_SAMPLES * 2 * 2]__attribute__ ((aligned(64)));
static unsigned long OGG_tempmixleft = 0;
static double OGG_newFilePos = -1;
static int OGG_tagRead = 0;
/////////////////////////////////////////////////////////////////////////////////////////
//Audio callback
/////////////////////////////////////////////////////////////////////////////////////////
static void oggDecodeThread(void *_buf2, unsigned int numSamples, void *pdata){
short *_buf = (short *)_buf2;
//static short OGG_mixBuffer[VITA_NUM_AUDIO_SAMPLES * 2 * 2]__attribute__ ((aligned(64)));
//static unsigned long OGG_tempmixleft = 0;
int current_section;
if (OGG_isPlaying) { // Playing , so mix up a buffer
outputInProgress = 1;
while (OGG_tempmixleft < numSamples) { // Not enough in buffer, so we must mix more
unsigned long bytesRequired = (numSamples - OGG_tempmixleft) * 4; // 2channels, 16bit = 4 bytes per sample
//unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, &current_section); //libtremor
unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, 0, 2, 1, &current_section); //ogg-vorbis
if (!ret) { //EOF
OGG_isPlaying = 0;
OGG_eos = 1;
outputInProgress = 0;
return;
} else if (ret < 0) {
if (ret == OV_HOLE)
continue;
OGG_isPlaying = 0;
OGG_eos = 1;
outputInProgress = 0;
return;
}
OGG_tempmixleft += ret / 4; // back down to sample num
}
OGG_info.instantBitrate = ov_bitrate_instant(&OGG_VorbisFile);
OGG_milliSeconds = ov_time_tell(&OGG_VorbisFile);
if (OGG_newFilePos >= 0)
{
ov_raw_seek(&OGG_VorbisFile, (ogg_int64_t)OGG_newFilePos);
OGG_newFilePos = -1;
}
//Check for playing speed:
if (OGG_playingSpeed){
if (ov_raw_seek(&OGG_VorbisFile, ov_raw_tell(&OGG_VorbisFile) + OGG_playingDelta) != 0)
OGG_setPlayingSpeed(0);
}
if (OGG_tempmixleft >= numSamples) { // Buffer has enough, so copy across
int count, count2;
short *_buf2;
//Volume boost:
if (!OGG_volume_boost){
for (count = 0; count < VITA_NUM_AUDIO_SAMPLES; count++) {
count2 = count + count;
_buf2 = _buf + count2;
*(_buf2) = OGG_mixBuffer[count2];
*(_buf2 + 1) = OGG_mixBuffer[count2 + 1];
}
}else{
for (count = 0; count < VITA_NUM_AUDIO_SAMPLES; count++) {
count2 = count + count;
_buf2 = _buf + count2;
*(_buf2) = volume_boost(&OGG_mixBuffer[count2], &OGG_volume_boost);
*(_buf2 + 1) = volume_boost(&OGG_mixBuffer[count2 + 1], &OGG_volume_boost);
}
}
// Move the pointers
OGG_tempmixleft -= numSamples;
// Now shuffle the buffer along
for (count = 0; count < OGG_tempmixleft * 2; count++)
OGG_mixBuffer[count] = OGG_mixBuffer[numSamples * 2 + count];
}
outputInProgress = 0;
} else { // Not Playing , so clear buffer
int count;
for (count = 0; count < numSamples * 2; count++)
*(_buf + count) = 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//Callback for vorbis
/////////////////////////////////////////////////////////////////////////////////////////
size_t ogg_callback_read(void *ptr, size_t size, size_t nmemb, void *datasource)
{
int res = sceIoRead(*(int *) datasource, ptr, size * nmemb);
if (res == 0x80010013) {
OGG_suspend();
OGG_resume();
res = sceIoRead(*(int *) datasource, ptr, size * nmemb);
}
return res;
}
int ogg_callback_seek(void *datasource, ogg_int64_t offset, int whence)
{
int res = sceIoLseek32(*(int *) datasource, (unsigned int) offset, whence);
if (res == 0x80010013) {
OGG_suspend();
OGG_resume();
res = sceIoLseek32(*(int *) datasource, (unsigned int) offset, whence);
}
return res;
}
long ogg_callback_tell(void *datasource)
{
int res = sceIoLseek32(*(int *) datasource, 0, SEEK_CUR);
if (res == 0x80010013) {
OGG_suspend();
OGG_resume();
res = sceIoLseek32(*(int *) datasource, 0, SEEK_CUR);
}
return (long)res;
}
int ogg_callback_close(void *datasource)
{
int res = sceIoClose(*(int *) datasource);
if (res == 0x80010013) {
OGG_suspend();
OGG_resume();
res = sceIoClose(*(int *) datasource);
}
return res;
}
void readOggTagData(char *source, char *dest){
int count = 0;
int i = 0;
strcpy(dest, "");
for (i=0; i<strlen(source); i++){
if ((unsigned char)source[i] >= 0x20 && (unsigned char)source[i] <= 0xfd){
dest[count] = source[i];
if (++count >= 256)
break;
}
}
dest[count] = '\0';
}
void splitComment(char *comment, char *name, char *value){
char *result = NULL;
result = strtok(comment, "=");
int count = 0;
while(result != NULL && count < 2){
if (strlen(result) > 0){
switch (count){
case 0:
strncpy(name, result, 30);
name[30] = '\0';
break;
case 1:
readOggTagData(result, value);
value[256] = '\0';
break;
}
count++;
}
result = strtok(NULL, "=");
}
}
void getOGGTagInfo(OggVorbis_File *inVorbisFile, struct fileInfo *targetInfo){
int i;
char name[31];
char value[257];
vorbis_comment *comment = ov_comment(inVorbisFile, -1);
for (i=0;i<comment->comments; i++){
splitComment(comment->user_comments[i], name, value);
if (!strcasecmp(name, "TITLE"))
strcpy(targetInfo->title, value);
else if(!strcasecmp(name, "ALBUM"))
strcpy(targetInfo->album, value);
else if(!strcasecmp(name, "ARTIST"))
strcpy(targetInfo->artist, value);
else if(!strcasecmp(name, "GENRE"))
strcpy(targetInfo->genre, value);
else if(!strcasecmp(name, "DATE") || !strcasecmp(name, "YEAR")){
strncpy(targetInfo->year, value, 4);
targetInfo->year[4] = '\0';
}else if(!strcasecmp(name, "TRACKNUMBER")){
strncpy(targetInfo->trackNumber, value, 7);
targetInfo->trackNumber[7] = '\0';
}
/*else if(!strcmp(name, "COVERART_UUENCODED")){
FILE *out = fopen("ms0:/coverart.jpg", "wb");
FILE *outEnc = fopen("ms0:/coverart.txt", "wb");
unsigned char base64Buffer[MAX_IMAGE_DIMENSION];
fwrite(&comment->user_comments[i][19], 1, comment->comment_lengths[i] - 19, outEnc);
int outChars = base64Decode(comment->comment_lengths[i], comment->user_comments[i], MAX_IMAGE_DIMENSION, base64Buffer);
fwrite(base64Buffer, 1, outChars, out);
fclose(outEnc);
fclose(out);
}*/
}
OGG_info = *targetInfo;
OGG_tagRead = 1;
}
void OGGgetInfo(){
//Estraggo le informazioni:
OGG_info.fileType = OGG_TYPE;
OGG_info.defaultCPUClock = OGG_defaultCPUClock;
OGG_info.needsME = 0;
vorbis_info *vi = ov_info(&OGG_VorbisFile, -1);
OGG_info.kbit = vi->bitrate_nominal/1000;
OGG_info.instantBitrate = vi->bitrate_nominal;
OGG_info.hz = vi->rate;
OGG_info.length = (long)ov_time_total(&OGG_VorbisFile, -1)/1000;
if (vi->channels == 1){
strcpy(OGG_info.mode, "single channel");
OGG_channels = 1;
}else if (vi->channels == 2){
strcpy(OGG_info.mode, "normal LR stereo");
OGG_channels = 2;
}
strcpy(OGG_info.emphasis, "no");
int h = 0;
int m = 0;
int s = 0;
long secs = OGG_info.length;
h = secs / 3600;
m = (secs - h * 3600) / 60;
s = secs - h * 3600 - m * 60;
snprintf(OGG_info.strLength, sizeof(OGG_info.strLength), "%2.2i:%2.2i:%2.2i", h, m, s);
if (!OGG_tagRead)
getOGGTagInfo(&OGG_VorbisFile, &OGG_info);
}
void OGG_Init(int channel){
initAudioLib();
MIN_PLAYING_SPEED=-119;
MAX_PLAYING_SPEED=119;
initFileInfo(&OGG_info);
OGG_tagRead = 0;
OGG_audio_channel = channel;
OGG_milliSeconds = 0.0;
OGG_tempmixleft = 0;
memset(OGG_mixBuffer, 0, sizeof(OGG_mixBuffer));
vitaAudioSetChannelCallback(OGG_audio_channel, oggDecodeThread, NULL);
}
int OGG_Load(char *filename){
outputInProgress = 0;
OGG_isPlaying = 0;
OGG_milliSeconds = 0;
OGG_eos = 0;
OGG_playingSpeed = 0;
OGG_playingDelta = 0;
strcpy(OGG_fileName, filename);
//Apro il file OGG:
OGG_file = sceIoOpen(OGG_fileName, SCE_O_RDONLY, 0777);
if (OGG_file >= 0) {
OGG_info.fileSize = sceIoLseek(OGG_file, 0, SCE_SEEK_END);
sceIoLseek(OGG_file, 0, SCE_SEEK_SET);
ov_callbacks ogg_callbacks;
ogg_callbacks.read_func = ogg_callback_read;
ogg_callbacks.seek_func = ogg_callback_seek;
ogg_callbacks.close_func = ogg_callback_close;
ogg_callbacks.tell_func = ogg_callback_tell;
if (ov_open_callbacks(&OGG_file, &OGG_VorbisFile, NULL, 0, ogg_callbacks) < 0){
sceIoClose(OGG_file);
OGG_file = -1;
return ERROR_OPENING;
}
}else{
return ERROR_OPENING;
}
OGGgetInfo();
//Controllo il sample rate:
if (vitaAudioSetFrequency(OGG_audio_channel, OGG_info.hz) < 0){
OGG_FreeTune();
return ERROR_INVALID_SAMPLE_RATE;
}
return OPENING_OK;
}
int OGG_IsPlaying() {
return OGG_isPlaying;
}
int OGG_Play(){
OGG_isPlaying = 1;
return 0;
}
void OGG_Pause(){
OGG_isPlaying = !OGG_isPlaying;
}
int OGG_Stop(){
OGG_isPlaying = 0;
//This is to be sure that oggDecodeThread isn't messing with &OGG_VorbisFile
while (outputInProgress == 1)
sceKernelDelayThread(100000);
return 0;
}
void OGG_FreeTune(){
ov_clear(&OGG_VorbisFile);
if (OGG_file >= 0)
sceIoClose(OGG_file);
OGG_file = -1;
OGG_tempmixleft = 0;
memset(OGG_mixBuffer, 0, sizeof(OGG_mixBuffer));
}
void OGG_GetTimeString(char *dest){
char timeString[9];
long secs = (long)OGG_milliSeconds/1000;
int h = secs / 3600;
int m = (secs - h * 3600) / 60;
int s = secs - h * 3600 - m * 60;
snprintf(timeString, sizeof(timeString), "%2.2i:%2.2i:%2.2i", h, m, s);
strcpy(dest, timeString);
}
int OGG_EndOfStream(){
return OGG_eos;
}
struct fileInfo *OGG_GetInfo(){
return &OGG_info;
}
struct fileInfo OGG_GetTagInfoOnly(char *filename){
int tempFile = -1;
OggVorbis_File vf;
struct fileInfo tempInfo;
strcpy(OGG_fileName, filename);
initFileInfo(&tempInfo);
//Apro il file OGG:
tempFile = sceIoOpen(filename, SCE_O_RDONLY, 0777);
if (tempFile >= 0) {
//sceIoLseek(tempFile, 0, SCE_SEEK_SET);
ov_callbacks ogg_callbacks;
ogg_callbacks.read_func = ogg_callback_read;
ogg_callbacks.seek_func = ogg_callback_seek;
ogg_callbacks.close_func = ogg_callback_close;
ogg_callbacks.tell_func = ogg_callback_tell;
if (ov_open_callbacks(&tempFile, &vf, NULL, 0, ogg_callbacks) < 0){
sceIoClose(tempFile);
return tempInfo;
}
getOGGTagInfo(&vf, &tempInfo);
ov_clear(&vf);
if (tempFile >= 0)
sceIoClose(tempFile);
}
return tempInfo;
}
float OGG_GetPercentage(){
float perc = 0.0f;
if (OGG_info.length){
perc = (float)(OGG_milliSeconds/1000.0/(double)OGG_info.length*100.0);
if (perc > 100)
perc = 100;
}
return perc;
}
void OGG_End(){
OGG_Stop();
vitaAudioSetChannelCallback(OGG_audio_channel, 0,0);
OGG_FreeTune();
endAudioLib();
}
int OGG_setMute(int onOff){
return setMute(OGG_audio_channel, onOff);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Fade out:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OGG_fadeOut(float seconds){
fadeOut(OGG_audio_channel, seconds);
}
void OGG_setVolumeBoost(int boost){
OGG_volume_boost = boost;
}
int OGG_getVolumeBoost(){
return OGG_volume_boost;
}
int OGG_setPlayingSpeed(int playingSpeed){
if (playingSpeed >= MIN_PLAYING_SPEED && playingSpeed <= MAX_PLAYING_SPEED){
OGG_playingSpeed = playingSpeed;
if (playingSpeed == 0)
setVolume(OGG_audio_channel, 0x8000);
else
setVolume(OGG_audio_channel, FASTFORWARD_VOLUME);
OGG_playingDelta = VITA_NUM_AUDIO_SAMPLES * (int)(OGG_playingSpeed/2);
return 0;
}else{
return -1;
}
}
int OGG_getPlayingSpeed(){
return OGG_playingSpeed;
}
int OGG_GetStatus(){
return 0;
}
void OGG_setVolumeBoostType(char *boostType){
//Only old method supported
MAX_VOLUME_BOOST = 4;
MIN_VOLUME_BOOST = 0;
}
//Functions for filter (equalizer):
int OGG_setFilter(double tFilter[32], int copyFilter){
return 0;
}
void OGG_enableFilter(){}
void OGG_disableFilter(){}
int OGG_isFilterSupported(){
return 0;
}
int OGG_isFilterEnabled(){
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Manage suspend:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int OGG_suspend(){
OGG_suspendPosition = ov_raw_tell(&OGG_VorbisFile);
OGG_suspendIsPlaying = OGG_isPlaying;
//OGG_Stop();
//OGG_FreeTune();
OGG_End();
return 0;
}
int OGG_resume(){
OGG_Init(OGG_audio_channel);
if (OGG_suspendPosition >= 0){
if (OGG_Load(OGG_fileName) == OPENING_OK){
if (ov_raw_seek(&OGG_VorbisFile, OGG_suspendPosition))
OGG_isPlaying = OGG_suspendIsPlaying;
}
OGG_suspendPosition = -1;
}
return 0;
}
double OGG_getFilePosition()
{
return (double)ov_raw_tell(&OGG_VorbisFile);
}
void OGG_setFilePosition(double position)
{
OGG_newFilePos = position;
}

55
audio/oggplayer.h Normal file
View File

@ -0,0 +1,55 @@
// LightMP3
// Copyright (C) 2007 Sakya
// sakya_tg@yahoo.it
//
// 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
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// 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.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
extern int OGG_defaultCPUClock;
//private functions
void OGG_Init(int channel);
int OGG_IsPlaying();
int OGG_Play();
void OGG_Pause();
int OGG_Stop();
void OGG_End();
void OGG_FreeTune();
int OGG_Load(char *filename);
void OGG_GetTimeString(char *dest);
int OGG_EndOfStream();
struct fileInfo *OGG_GetInfo();
struct fileInfo OGG_GetTagInfoOnly(char *filename);
int OGG_GetStatus();
float OGG_GetPercentage();
void OGG_setVolumeBoostType(char *boostType);
void OGG_setVolumeBoost(int boost);
int OGG_getVolumeBoost();
int OGG_getPlayingSpeed();
int OGG_setPlayingSpeed(int playingSpeed);
int OGG_setMute(int onOff);
void OGG_fadeOut(float seconds);
//Functions for filter (equalizer):
int OGG_setFilter(double tFilter[32], int copyFilter);
void OGG_enableFilter();
void OGG_disableFilter();
int OGG_isFilterEnabled();
int OGG_isFilterSupported();
//Manage suspend:
int OGG_suspend();
int OGG_resume();
double OGG_getFilePosition();
void OGG_setFilePosition(double position);

View File

@ -17,16 +17,53 @@
*/
#include <psp2/io/fcntl.h>
#include <psp2/kernel/threadmgr.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "player.h"
#include "mp3player.h"
#include "oggplayer.h"
#include "vita_audio.h"
int MAX_VOLUME_BOOST=15;
int MIN_VOLUME_BOOST=-15;
int MIN_PLAYING_SPEED=-119;
int MAX_PLAYING_SPEED=119;
#include "../file.h"
int MUTED_VOLUME = 800;
int MAX_VOLUME_BOOST = 15;
int MIN_VOLUME_BOOST = -15;
int MIN_PLAYING_SPEED = -119;
int MAX_PLAYING_SPEED = 119;
int currentVolume = 0;
void (* initFunct)(int);
int (* isPlayingFunct)();
int (* loadFunct)(char *);
int (* playFunct)();
void (* pauseFunct)();
void (* endFunct)();
void (* setVolumeBoostTypeFunct)(char*);
void (* setVolumeBoostFunct)(int);
struct fileInfo *(* getInfoFunct)();
struct fileInfo (* getTagInfoFunct)();
void (* getTimeStringFunct)();
float (* getPercentageFunct)();
int (* getPlayingSpeedFunct)();
int (* setPlayingSpeedFunct)(int);
int (* endOfStreamFunct)();
int (* setMuteFunct)(int);
int (* setFilterFunct)(double[32], int copyFilter);
void (* enableFilterFunct)();
void (* disableFilterFunct)();
int (* isFilterEnabledFunct)();
int (* isFilterSupportedFunct)();
int (* suspendFunct)();
int (* resumeFunct)();
void (* fadeOutFunct)(float seconds);
double (* getFilePositionFunct)();
void (* setFilePositionFunct)(double positionInSecs);
//Seek next valid frame
//NOTE: this function comes from Music prx 0.55 source
@ -86,20 +123,136 @@ int SeekNextFrameMP3(SceUID fd)
}
}
int setAudioFunctions(int type) {
if (type == FILE_TYPE_OGG) {
//OGG Vorbis
initFunct = OGG_Init;
loadFunct = OGG_Load;
isPlayingFunct = OGG_IsPlaying;
playFunct = OGG_Play;
pauseFunct = OGG_Pause;
endFunct = OGG_End;
setVolumeBoostTypeFunct = OGG_setVolumeBoostType;
setVolumeBoostFunct = OGG_setVolumeBoost;
getInfoFunct = OGG_GetInfo;
getTagInfoFunct = OGG_GetTagInfoOnly;
getTimeStringFunct = OGG_GetTimeString;
getPercentageFunct = OGG_GetPercentage;
getPlayingSpeedFunct = OGG_getPlayingSpeed;
setPlayingSpeedFunct = OGG_setPlayingSpeed;
endOfStreamFunct = OGG_EndOfStream;
setMuteFunct = OGG_setMute;
setFilterFunct = OGG_setFilter;
enableFilterFunct = OGG_enableFilter;
disableFilterFunct = OGG_disableFilter;
isFilterEnabledFunct = OGG_isFilterEnabled;
isFilterSupportedFunct = OGG_isFilterSupported;
suspendFunct = OGG_suspend;
resumeFunct = OGG_resume;
fadeOutFunct = OGG_fadeOut;
getFilePositionFunct = OGG_getFilePosition;
setFilePositionFunct = OGG_setFilePosition;
return 0;
} else if (type == FILE_TYPE_MP3) {
initFunct = MP3_Init;
loadFunct = MP3_Load;
isPlayingFunct = MP3_IsPlaying;
playFunct = MP3_Play;
pauseFunct = MP3_Pause;
endFunct = MP3_End;
setVolumeBoostTypeFunct = MP3_setVolumeBoostType;
setVolumeBoostFunct = MP3_setVolumeBoost;
getInfoFunct = MP3_GetInfo;
getTagInfoFunct = MP3_GetTagInfoOnly;
getTimeStringFunct = MP3_GetTimeString;
getPercentageFunct = MP3_GetPercentage;
getPlayingSpeedFunct = MP3_getPlayingSpeed;
setPlayingSpeedFunct = MP3_setPlayingSpeed;
endOfStreamFunct = MP3_EndOfStream;
setMuteFunct = MP3_setMute;
setFilterFunct = MP3_setFilter;
enableFilterFunct = MP3_enableFilter;
disableFilterFunct = MP3_disableFilter;
isFilterEnabledFunct = MP3_isFilterEnabled;
isFilterSupportedFunct = MP3_isFilterSupported;
suspendFunct = MP3_suspend;
resumeFunct = MP3_resume;
fadeOutFunct = MP3_fadeOut;
getFilePositionFunct = MP3_getFilePosition;
setFilePositionFunct = MP3_setFilePosition;
return 0;
}
return -1;
}
void unsetAudioFunctions() {
initFunct = NULL;
loadFunct = NULL;
playFunct = NULL;
pauseFunct = NULL;
endFunct = NULL;
setVolumeBoostTypeFunct = NULL;
setVolumeBoostFunct = NULL;
getInfoFunct = NULL;
getTagInfoFunct = NULL;
getTimeStringFunct = NULL;
getPercentageFunct = NULL;
getPlayingSpeedFunct = NULL;
setPlayingSpeedFunct = NULL;
endOfStreamFunct = NULL;
setMuteFunct = NULL;
setFilterFunct = NULL;
enableFilterFunct = NULL;
disableFilterFunct = NULL;
isFilterEnabledFunct = NULL;
isFilterSupportedFunct = NULL;
suspendFunct = NULL;
resumeFunct = NULL;
getFilePositionFunct = NULL;
setFilePositionFunct = NULL;
}
short volume_boost(short *Sample, unsigned int *boost) {
return 0;
int intSample = *Sample * (*boost + 1);
if (intSample > 32767)
return 32767;
else if (intSample < -32768)
return -32768;
else
return intSample;
}
int setVolume(int channel, int volume) {
vitaAudioSetVolume(channel, volume, volume);
return 0;
}
int setMute(int channel, int onOff) {
if (onOff)
setVolume(channel, MUTED_VOLUME);
else
setVolume(channel, VITA_VOLUME_MAX);
return 0;
}
void fadeOut(int channel, float seconds) {
int i = 0;
long timeToWait = (long)((seconds * 1000.0) / (float)currentVolume);
for (i=currentVolume; i>=0; i--){
vitaAudioSetVolume(channel, i, i);
sceKernelDelayThread(timeToWait);
}
}
int initAudioLib() {

View File

@ -19,7 +19,9 @@
#ifndef __PLAYER_H__
#define __PLAYER_H__
#include "id3.h"
#include "info.h"
#include "vita_audio.h"
#define OPENING_OK 0
#define ERROR_OPENING -1
@ -29,15 +31,9 @@
#define MP3_TYPE 0
#define OGG_TYPE 1
#define AT3_TYPE 2
#define FLAC_TYPE 3
#define AAC_TYPE 4
#define WMA_TYPE 5
#define UNK_TYPE -1
#define FASTFORWARD_VOLUME 0x2200
#define MAX_IMAGE_DIMENSION 300*1024
#define DEFAULT_THREAD_STACK_SIZE 256*1024
#define FASTFORWARD_VOLUME 0 // 0x2200
extern int MAX_VOLUME_BOOST;
extern int MIN_VOLUME_BOOST;
@ -56,4 +52,36 @@ int endAudioLib();
void initFileInfo(struct fileInfo *info);
extern void (* initFunct)(int);
extern int (* loadFunct)(char *);
extern int (* isPlayingFunct)();
extern int (* playFunct)();
extern void (* pauseFunct)();
extern void (* endFunct)();
extern void (* setVolumeBoostTypeFunct)(char*);
extern void (* setVolumeBoostFunct)(int);
extern struct fileInfo *(* getInfoFunct)();
extern struct fileInfo (* getTagInfoFunct)();
extern void (* getTimeStringFunct)();
extern float (* getPercentageFunct)();
extern int (* getPlayingSpeedFunct)();
extern int (* setPlayingSpeedFunct)(int);
extern int (* endOfStreamFunct)();
extern int (* setMuteFunct)(int);
extern int (* setFilterFunct)(double[32], int copyFilter);
extern void (* enableFilterFunct)();
extern void (* disableFilterFunct)();
extern int (* isFilterEnabledFunct)();
extern int (* isFilterSupportedFunct)();
extern int (* suspendFunct)();
extern int (* resumeFunct)();
extern void (* fadeOutFunct)(float seconds);
extern double (* getFilePositionFunct)(); //Gets current file position in bytes
extern void (* setFilePositionFunct)(double position); //Set current file position in butes
extern int setAudioFunctions(int type);
extern void unsetAudioFunctions();
#endif

View File

@ -6,8 +6,6 @@
#include <malloc.h>
#include "vita_audio.h"
#define VITA_WAV_MAX_SLOTS 128
static vitaWav vitaWavInfo[VITA_WAV_MAX_SLOTS];
static int vitaWavPlaying[VITA_WAV_MAX_SLOTS];
static int vitaWavId[VITA_WAV_MAX_SLOTS];
@ -18,12 +16,6 @@ static int vitaWavIdFlag = 0;
static int vitaWavInitFlag = 0;
#define VITA_NUM_AUDIO_CHANNELS 1 // 4
#define VITA_NUM_AUDIO_SAMPLES 1024
#define VITA_VOLUME_MAX 0x8000
typedef void (* vitaAudioCallback)(void *buf, unsigned int reqn, void *pdata);
typedef struct
{
int threadHandle;
@ -42,8 +34,13 @@ static vitaAudioChannelInfo vitaAudioStatus[VITA_NUM_AUDIO_CHANNELS];
static volatile int vitaAudioTerminate = 0;
void vitaAudioSetVolume(int channel, int left, int right) {
vitaAudioStatus[channel].volumeLeft = left;
vitaAudioStatus[channel].volumeRight = right;
}
int vitaAudioSetFrequency(int channel, unsigned short freq) {
return 0;
return sceAudioOutSetConfig(vitaAudioStatus[channel].handle, VITA_NUM_AUDIO_SAMPLES, freq, SCE_AUDIO_OUT_MODE_STEREO);
}
void vitaAudioSetChannelCallback(int channel, vitaAudioCallback callback, void *data)

View File

@ -14,6 +14,14 @@
extern "C" {
#endif
#define VITA_WAV_MAX_SLOTS 128
#define VITA_NUM_AUDIO_CHANNELS 1 // 4
#define VITA_NUM_AUDIO_SAMPLES 1024
#define VITA_VOLUME_MAX 0x8000
typedef void (* vitaAudioCallback)(void *buf, unsigned int reqn, void *pdata);
/** @defgroup vitaWav WAV Library
* @{
*/
@ -109,6 +117,11 @@ void vitaWavLoop(vitaWav *wav, unsigned int loop);
/** @} */
void vitaAudioSetVolume(int channel, int left, int right);
int vitaAudioSetFrequency(int channel, unsigned short freq);
void vitaAudioSetChannelCallback(int channel, vitaAudioCallback callback, void *data);
int vitaAudioInit(int priority);
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@ -21,19 +21,18 @@
#include "audioplayer.h"
#include "file.h"
#include "theme.h"
#include "language.h"
#include "utils.h"
#include "audio/id3.h"
#include "audio/info.h"
#include "audio/mp3player.h"
#include "audio/player.h"
struct fileInfo *fileinfo = NULL;
vita2d_texture *tex = NULL;
void getMp3Info(char *file) {
void getAudioInfo(char *file) {
char *buffer = NULL;
fileinfo = MP3_GetInfo();
fileinfo = getInfoFunct();
if (tex) {
vita2d_free_texture(tex);
@ -58,6 +57,9 @@ void getMp3Info(char *file) {
if (fileinfo->encapsulatedPictureType == PNG_IMAGE)
tex = vita2d_load_PNG_buffer(buffer);
if (tex)
vita2d_texture_set_filters(tex, SCE_GXM_TEXTURE_FILTER_LINEAR, SCE_GXM_TEXTURE_FILTER_LINEAR);
free(buffer);
}
@ -68,11 +70,20 @@ void getMp3Info(char *file) {
}
int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int *base_pos, int *rel_pos) {
MP3_Init(0);
MP3_Load(file);
MP3_Play();
static int speed_list[] = { -7, -3, -1, 0, 1, 3, 7 };
#define N_SPEED (sizeof(speed_list) / sizeof(int))
getMp3Info(file);
sceAppMgrAcquireBgmPort();
powerLock();
setAudioFunctions(type);
initFunct(0);
loadFunct(file);
playFunct();
getAudioInfo(file);
while (1) {
readPad();
@ -82,8 +93,51 @@ int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int
break;
}
// Display off
if (pressed_buttons & SCE_CTRL_TRIANGLE) {
scePowerRequestDisplayOff();
}
// Toggle play/pause
if (pressed_buttons & SCE_CTRL_ENTER) {
if (isPlayingFunct() && getPlayingSpeedFunct() == 0) {
pauseFunct();
} else {
setPlayingSpeedFunct(0);
playFunct();
}
}
if (pressed_buttons & SCE_CTRL_LEFT || pressed_buttons & SCE_CTRL_RIGHT) {
int speed = getPlayingSpeedFunct();
if (pressed_buttons & SCE_CTRL_LEFT) {
int i;
for (i = 0; i < N_SPEED; i++) {
if (speed_list[i] == speed) {
if (i > 0)
speed = speed_list[i - 1];
break;
}
}
}
if (pressed_buttons & SCE_CTRL_RIGHT) {
int i;
for (i = 0; i < N_SPEED; i++) {
if (speed_list[i] == speed) {
if (i < N_SPEED - 1)
speed = speed_list[i + 1];
break;
}
}
}
setPlayingSpeedFunct(speed);
}
// Previous/next song.
if (MP3_EndOfStream() || pressed_buttons & SCE_CTRL_LTRIGGER || pressed_buttons & SCE_CTRL_RTRIGGER) {
if (getPercentageFunct() == 100.0f || endOfStreamFunct() || pressed_buttons & SCE_CTRL_LTRIGGER || pressed_buttons & SCE_CTRL_RTRIGGER) {
int available = 0;
int old_base_pos = *base_pos;
@ -91,7 +145,11 @@ int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int
FileListEntry *old_entry = entry;
int previous = pressed_buttons & SCE_CTRL_LTRIGGER;
if (MP3_EndOfStream())
if (getPercentageFunct() == 100.0f && !endOfStreamFunct())
previous = 1;
if (endOfStreamFunct())
previous = 0;
while (previous ? entry->previous : entry->next) {
@ -121,12 +179,19 @@ int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int
char path[MAX_PATH_LENGTH];
snprintf(path, MAX_PATH_LENGTH, "%s%s", list->path, entry->name);
int type = getFileType(path);
if (type == FILE_TYPE_MP3) {
MP3_End();
MP3_Init(0);
MP3_Load(path);
MP3_Play();
getMp3Info(path);
if (type == FILE_TYPE_MP3 || type == FILE_TYPE_OGG) {
file = path;
endFunct();
setAudioFunctions(type);
initFunct(0);
loadFunct(file);
playFunct();
getAudioInfo(file);
available = 1;
break;
}
@ -147,25 +212,68 @@ int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int
// Draw shell info
drawShellInfo(file);
pgf_draw_textf(SHELL_MARGIN_X, START_Y + (0 * FONT_Y_SPACE), 0xFFFFFFFF, FONT_SIZE, fileinfo->artist);
pgf_draw_textf(SHELL_MARGIN_X, START_Y + (1 * FONT_Y_SPACE), 0xFFFFFFFF, FONT_SIZE, fileinfo->title);
pgf_draw_textf(SHELL_MARGIN_X, START_Y + (2 * FONT_Y_SPACE), 0xFFFFFFFF, FONT_SIZE, fileinfo->album);
float cover_size = MAX_ENTRIES * FONT_Y_SPACE;
// Picture
if (tex)
vita2d_draw_texture_scale(tex, SHELL_MARGIN_X, 200.0f, 1.0f, 1.0f);
// Cover
if (tex) {
vita2d_draw_texture_scale(tex, SHELL_MARGIN_X, START_Y, cover_size / vita2d_texture_get_width(tex), cover_size / vita2d_texture_get_height(tex));
} else {
vita2d_draw_texture(cover_image, SHELL_MARGIN_X, START_Y);
}
float x = 2.0f * SHELL_MARGIN_X + cover_size;
pgf_draw_text(x, START_Y + (0 * FONT_Y_SPACE), AUDIO_INFO_ASSIGN, FONT_SIZE, language_container[TITLE]);
pgf_draw_text(x, START_Y + (1 * FONT_Y_SPACE), AUDIO_INFO_ASSIGN, FONT_SIZE, language_container[ALBUM]);
pgf_draw_text(x, START_Y + (2 * FONT_Y_SPACE), AUDIO_INFO_ASSIGN, FONT_SIZE, language_container[ARTIST]);
pgf_draw_text(x, START_Y + (3 * FONT_Y_SPACE), AUDIO_INFO_ASSIGN, FONT_SIZE, language_container[GENRE]);
pgf_draw_text(x, START_Y + (4 * FONT_Y_SPACE), AUDIO_INFO_ASSIGN, FONT_SIZE, language_container[YEAR]);
pgf_draw_text(x + 120.0f, START_Y + (0 * FONT_Y_SPACE), AUDIO_INFO, FONT_SIZE, fileinfo->title[0] == '\0' ? "-" : fileinfo->title);
pgf_draw_text(x + 120.0f, START_Y + (1 * FONT_Y_SPACE), AUDIO_INFO, FONT_SIZE, fileinfo->album[0] == '\0' ? "-" : fileinfo->album);
pgf_draw_text(x + 120.0f, START_Y + (2 * FONT_Y_SPACE), AUDIO_INFO, FONT_SIZE, fileinfo->artist[0] == '\0' ? "-" : fileinfo->artist);
pgf_draw_text(x + 120.0f, START_Y + (3 * FONT_Y_SPACE), AUDIO_INFO, FONT_SIZE, fileinfo->genre[0] == '\0' ? "-" : fileinfo->genre);
pgf_draw_text(x + 120.0f, START_Y + (4 * FONT_Y_SPACE), AUDIO_INFO, FONT_SIZE, fileinfo->year[0] == '\0' ? "-" : fileinfo->year);
float y = SCREEN_HEIGHT - 6.0f * SHELL_MARGIN_Y;
// Icon
vita2d_texture *icon = NULL;
if (getPlayingSpeedFunct() != 0) {
if (getPlayingSpeedFunct() < 0) {
icon = fastrewind_image;
} else {
icon = fastforward_image;
}
pgf_draw_textf(x + 45.0f, y, AUDIO_SPEED, FONT_SIZE, "%dx", abs(getPlayingSpeedFunct() + (getPlayingSpeedFunct() < 0 ? -1 : 1)));
} else {
if (isPlayingFunct()) {
icon = play_image;
} else {
icon = pause_image;
}
}
vita2d_draw_texture(icon, x, y + 3.0f);
// Time
char string[12];
MP3_GetTimeString(string);
char cur_time_string[12];
getTimeStringFunct(cur_time_string);
char string[32];
sprintf(string, "%s / %s", cur_time_string, fileinfo->strLength);
float time_x = ALIGN_LEFT(SCREEN_WIDTH - SHELL_MARGIN_X, vita2d_pgf_text_width(font, FONT_SIZE, string));
int w = pgf_draw_text(time_x, y, AUDIO_TIME_CURRENT, FONT_SIZE, cur_time_string);
pgf_draw_text(time_x + (float)w, y, AUDIO_TIME_SLASH, FONT_SIZE, " /");
pgf_draw_text(ALIGN_LEFT(SCREEN_WIDTH - SHELL_MARGIN_X, vita2d_pgf_text_width(font, FONT_SIZE, fileinfo->strLength)), y, AUDIO_TIME_TOTAL, FONT_SIZE, fileinfo->strLength);
float width = SCREEN_WIDTH - 3.0f * SHELL_MARGIN_X - cover_size;
vita2d_draw_rectangle(x, (y) + FONT_Y_SPACE + 10.0f, width, 8, AUDIO_TIME_BAR_BG);
vita2d_draw_rectangle(x, (y) + FONT_Y_SPACE + 10.0f, getPercentageFunct() * width / 100.0f, 8, AUDIO_TIME_BAR);
pgf_draw_textf(SHELL_MARGIN_X, SCREEN_HEIGHT - 3.0f * SHELL_MARGIN_Y, PHOTO_ZOOM_COLOR, FONT_SIZE, "%s/%s", string, fileinfo->strLength);
/*
//float percent = MP3_GetPercentage();
float width = uncommon_dialog.width - 2.0f * SHELL_MARGIN_X;
vita2d_draw_rectangle(uncommon_dialog.x + SHELL_MARGIN_X, string_y + 10.0f, width, UNCOMMON_DIALOG_PROGRESS_BAR_HEIGHT, PROGRESS_BAR_BG_COLOR);
vita2d_draw_rectangle(uncommon_dialog.x + SHELL_MARGIN_X, string_y + 10.0f, uncommon_dialog.progress * width / 100.0f, UNCOMMON_DIALOG_PROGRESS_BAR_HEIGHT, PROGRESS_BAR_COLOR);
*/
// End drawing
endDrawing();
}
@ -175,7 +283,11 @@ int audioPlayer(char *file, int type, FileList *list, FileListEntry *entry, int
tex = NULL;
}
MP3_End();
endFunct();
powerUnlock();
sceAppMgrReleaseBgmPort();
return 0;
}

1
file.c
View File

@ -538,6 +538,7 @@ static ExtensionType extension_types[] = {
{ ".JPG", FILE_TYPE_JPEG },
{ ".JPEG", FILE_TYPE_JPEG },
{ ".MP3", FILE_TYPE_MP3 },
{ ".OGG", FILE_TYPE_OGG },
{ ".PNG", FILE_TYPE_PNG },
{ ".SFO", FILE_TYPE_SFO },
{ ".TXT", FILE_TYPE_TXT },

1
file.h
View File

@ -35,6 +35,7 @@ enum FileTypes {
FILE_TYPE_INI,
FILE_TYPE_JPEG,
FILE_TYPE_MP3,
FILE_TYPE_OGG,
FILE_TYPE_PNG,
FILE_TYPE_SFO,
FILE_TYPE_TXT,

93
init.c
View File

@ -21,59 +21,56 @@
#include "file.h"
#include "utils.h"
extern unsigned char _binary_resources_changeinfo_txt_start;
extern unsigned char _binary_resources_changeinfo_txt_size;
INCLUDE_EXTERN_RESOURCE(changeinfo_txt);
extern unsigned char _binary_resources_folder_icon_png_start;
extern unsigned char _binary_resources_folder_icon_png_size;
extern unsigned char _binary_resources_file_icon_png_start;
extern unsigned char _binary_resources_file_icon_png_size;
extern unsigned char _binary_resources_archive_icon_png_start;
extern unsigned char _binary_resources_archive_icon_png_size;
extern unsigned char _binary_resources_image_icon_png_start;
extern unsigned char _binary_resources_image_icon_png_size;
extern unsigned char _binary_resources_audio_icon_png_start;
extern unsigned char _binary_resources_audio_icon_png_size;
extern unsigned char _binary_resources_sfo_icon_png_start;
extern unsigned char _binary_resources_sfo_icon_png_size;
extern unsigned char _binary_resources_text_icon_png_start;
extern unsigned char _binary_resources_text_icon_png_size;
extern unsigned char _binary_resources_ftp_png_start;
extern unsigned char _binary_resources_ftp_png_size;
extern unsigned char _binary_resources_battery_png_start;
extern unsigned char _binary_resources_battery_png_size;
extern unsigned char _binary_resources_battery_bar_red_png_start;
extern unsigned char _binary_resources_battery_bar_red_png_size;
extern unsigned char _binary_resources_battery_bar_green_png_start;
extern unsigned char _binary_resources_battery_bar_green_png_size;
extern unsigned char _binary_resources_battery_bar_charge_png_start;
extern unsigned char _binary_resources_battery_bar_charge_png_size;
extern unsigned char _binary_resources_theme_txt_start;
extern unsigned char _binary_resources_theme_txt_size;
INCLUDE_EXTERN_RESOURCE(folder_icon_png);
INCLUDE_EXTERN_RESOURCE(file_icon_png);
INCLUDE_EXTERN_RESOURCE(archive_icon_png);
INCLUDE_EXTERN_RESOURCE(image_icon_png);
INCLUDE_EXTERN_RESOURCE(audio_icon_png);
INCLUDE_EXTERN_RESOURCE(sfo_icon_png);
INCLUDE_EXTERN_RESOURCE(text_icon_png);
INCLUDE_EXTERN_RESOURCE(ftp_png);
INCLUDE_EXTERN_RESOURCE(battery_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_red_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_green_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_charge_png);
extern unsigned char _binary_resources_colors_txt_start;
extern unsigned char _binary_resources_colors_txt_size;
INCLUDE_EXTERN_RESOURCE(cover_png);
INCLUDE_EXTERN_RESOURCE(play_png);
INCLUDE_EXTERN_RESOURCE(pause_png);
INCLUDE_EXTERN_RESOURCE(fastforward_png);
INCLUDE_EXTERN_RESOURCE(fastrewind_png);
extern unsigned char _binary_resources_english_us_txt_start;
extern unsigned char _binary_resources_english_us_txt_size;
INCLUDE_EXTERN_RESOURCE(theme_txt);
INCLUDE_EXTERN_RESOURCE(colors_txt);
INCLUDE_EXTERN_RESOURCE(english_us_txt);
#define DEFAULT_FILE(pah, name) { "ux0:VitaShell/language/english_us.txt", (void *)&_binary_resources_##name##_start, (int)&_binary_resources_##name##_size }
static DefaultFile default_files[] = {
{ "ux0:VitaShell/language/english_us.txt", (void *)&_binary_resources_english_us_txt_start, (int)&_binary_resources_english_us_txt_size },
{ "ux0:VitaShell/theme/theme.txt", (void *)&_binary_resources_theme_txt_start, (int)&_binary_resources_theme_txt_size },
{ "ux0:VitaShell/theme/Default/colors.txt", (void *)&_binary_resources_colors_txt_start, (int)&_binary_resources_colors_txt_size },
{ "ux0:VitaShell/theme/Default/folder_icon.png", (void *)&_binary_resources_folder_icon_png_start, (int)&_binary_resources_folder_icon_png_size },
{ "ux0:VitaShell/theme/Default/file_icon.png", (void *)&_binary_resources_file_icon_png_start, (int)&_binary_resources_file_icon_png_size },
{ "ux0:VitaShell/theme/Default/archive_icon.png", (void *)&_binary_resources_archive_icon_png_start, (int)&_binary_resources_archive_icon_png_size },
{ "ux0:VitaShell/theme/Default/image_icon.png", (void *)&_binary_resources_image_icon_png_start, (int)&_binary_resources_image_icon_png_size },
{ "ux0:VitaShell/theme/Default/audio_icon.png", (void *)&_binary_resources_audio_icon_png_start, (int)&_binary_resources_audio_icon_png_size },
{ "ux0:VitaShell/theme/Default/sfo_icon.png", (void *)&_binary_resources_sfo_icon_png_start, (int)&_binary_resources_sfo_icon_png_size },
{ "ux0:VitaShell/theme/Default/text_icon.png", (void *)&_binary_resources_text_icon_png_start, (int)&_binary_resources_text_icon_png_size },
{ "ux0:VitaShell/theme/Default/ftp.png", (void *)&_binary_resources_ftp_png_start, (int)&_binary_resources_ftp_png_size },
{ "ux0:VitaShell/theme/Default/battery.png", (void *)&_binary_resources_battery_png_start, (int)&_binary_resources_battery_png_size },
{ "ux0:VitaShell/theme/Default/battery_bar_red.png", (void *)&_binary_resources_battery_bar_red_png_start, (int)&_binary_resources_battery_bar_red_png_size },
{ "ux0:VitaShell/theme/Default/battery_bar_green.png", (void *)&_binary_resources_battery_bar_green_png_start, (int)&_binary_resources_battery_bar_green_png_size },
{ "ux0:VitaShell/theme/Default/battery_bar_charge.png", (void *)&_binary_resources_battery_bar_charge_png_start, (int)&_binary_resources_battery_bar_charge_png_size },
DEFAULT_FILE("ux0:VitaShell/language/english_us.txt", english_us_txt),
DEFAULT_FILE("ux0:VitaShell/theme/theme.txt", theme_txt),
DEFAULT_FILE("ux0:VitaShell/theme/Default/colors.txt", colors_txt),
DEFAULT_FILE("ux0:VitaShell/theme/Default/folder_icon.png", folder_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/file_icon.png", file_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/archive_icon.png", archive_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/image_icon.png", image_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/audio_icon.png", audio_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/sfo_icon.png", sfo_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/text_icon.png", text_icon_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/ftp.png", ftp_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/battery.png", battery_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/battery_bar_red.png", battery_bar_red_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/battery_bar_green.png", battery_bar_green_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/battery_bar_charge.png", battery_bar_charge_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/cover.png", cover_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/play.png", play_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/pause.png", pause_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/fastforward.png", fastforward_png),
DEFAULT_FILE("ux0:VitaShell/theme/Default/fastrewind.png", fastrewind_png),
};
vita2d_pgf *font = NULL;

View File

@ -20,8 +20,7 @@
#include "config.h"
#include "language.h"
extern unsigned char _binary_resources_english_us_txt_start;
extern unsigned char _binary_resources_english_us_txt_size;
INCLUDE_EXTERN_RESOURCE(english_us_txt);
static char *lang[] ={
"japanese",
@ -80,6 +79,13 @@ void loadLanguage(int id) {
LANGUAGE_ENTRY(EXTRACTING),
LANGUAGE_ENTRY(HASHING),
// Audio player strings
LANGUAGE_ENTRY(TITLE),
LANGUAGE_ENTRY(ALBUM),
LANGUAGE_ENTRY(ARTIST),
LANGUAGE_ENTRY(GENRE),
LANGUAGE_ENTRY(YEAR),
// Hex editor strings
LANGUAGE_ENTRY(CUT),
LANGUAGE_ENTRY(OPEN_HEX_EDITOR),

View File

@ -37,6 +37,13 @@ enum LanguageContainer {
EXTRACTING,
HASHING,
// Audio player strings
TITLE,
ALBUM,
ARTIST,
GENRE,
YEAR,
// Hex editor strings
OFFSET,
OPEN_HEX_EDITOR,

View File

@ -24,7 +24,7 @@
extern "C" {
# endif
# define FPM_INTEL
# define FPM_DEFAULT

8
main.c
View File

@ -46,6 +46,8 @@
#include "utils.h"
#include "sfo.h"
#include "audio/vita_audio.h"
int _newlib_heap_size_user = 64 * 1024 * 1024;
#define MAX_DIR_LEVELS 1024
@ -260,6 +262,8 @@ int handleFile(char *file, FileListEntry *entry) {
int type = getFileType(file);
switch (type) {
case FILE_TYPE_MP3:
case FILE_TYPE_OGG:
case FILE_TYPE_VPK:
case FILE_TYPE_ZIP:
if (isInArchive())
@ -283,6 +287,7 @@ int handleFile(char *file, FileListEntry *entry) {
break;
case FILE_TYPE_MP3:
case FILE_TYPE_OGG:
res = audioPlayer(file, type, &file_list, entry, &base_pos, &rel_pos);
break;
@ -1404,6 +1409,7 @@ int shellMain() {
break;
case FILE_TYPE_MP3:
case FILE_TYPE_OGG:
color = IMAGE_COLOR;
icon = audio_icon;
break;
@ -1568,7 +1574,7 @@ int main(int argc, const char *argv[]) {
initTextContextMenuWidth();
// Automatic network update
SceUID thid = sceKernelCreateThread("network_update_thread", (SceKernelThreadEntry)network_update_thread, 0x40, 0x10000, 0, 0, NULL);
SceUID thid = sceKernelCreateThread("network_update_thread", (SceKernelThreadEntry)network_update_thread, 0x10000100, 0x10000, 0, 0, NULL);
if (thid >= 0)
sceKernelStartThread(thid, 0, NULL);

2
main.h
View File

@ -61,6 +61,8 @@
#include "functions.h"
#define INCLUDE_EXTERN_RESOURCE(name) extern unsigned char _binary_resources_##name##_start; extern unsigned char _binary_resources_##name##_size; \
#define ENABLE_FILE_LOGGING 1
// VitaShell version major.minor

View File

@ -199,7 +199,7 @@ int network_update_thread(SceSize args, void *argp) {
// Wait for response
while (dialog_step == DIALOG_STEP_UPDATE_QUESTION) {
sceKernelDelayThread(1000);
sceKernelDelayThread(10 * 1000);
}
// No

View File

@ -366,7 +366,7 @@ int install_thread(SceSize args_size, InstallArguments *args) {
// Wait for response
while (dialog_step == DIALOG_STEP_INSTALL_WARNING) {
sceKernelDelayThread(1000);
sceKernelDelayThread(10 * 1000);
}
// Cancelled

View File

@ -44,4 +44,14 @@ TEXT_LINE_NUMBER_COLOR_FOCUS = 0xFF7F7F7F # Gray
TEXT_HIGHLIGHT_COLOR = 0xFF80F5FF # Yellow
# Photo viewer colors
PHOTO_ZOOM_COLOR = 0xFFFFFFFF # White
PHOTO_ZOOM_COLOR = 0xFFFFFFFF # White
# Audio player colors
AUDIO_INFO_ASSIGN = 0xFFFFFF00 # Cyan
AUDIO_INFO = 0xFFFFFFFF # White
AUDIO_SPEED = 0xFFFFFFFF # White
AUDIO_TIME_CURRENT = 0xFF00FF00 # Green
AUDIO_TIME_SLASH = 0xFFFFFFFF # White
AUDIO_TIME_TOTAL = 0xFFFFFFFF # White
AUDIO_TIME_BAR = 0xFFFF7F00 # Azure
AUDIO_TIME_BAR_BG = 0xFF7F7F7F # Gray

BIN
resources/cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -17,6 +17,13 @@ DOWNLOADING = "Downloading..."
EXTRACTING = "Extracting..."
HASHING = "Hashing..."
# Audio player strings
TITLE = "Title"
ALBUM = "Album"
ARTIST = "Artist"
GENRE = "Genre"
YEAR = "Year"
# Hex editor strings
OFFSET = "Offset"
OPEN_HEX_EDITOR = "Open hex editor"

BIN
resources/fastforward.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

BIN
resources/fastrewind.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

BIN
resources/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

BIN
resources/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

BIN
resources/stop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

86
theme.c
View File

@ -22,21 +22,27 @@
#include "theme.h"
#include "utils.h"
extern unsigned char _binary_resources_folder_icon_png_start;
extern unsigned char _binary_resources_file_icon_png_start;
extern unsigned char _binary_resources_archive_icon_png_start;
extern unsigned char _binary_resources_image_icon_png_start;
extern unsigned char _binary_resources_audio_icon_png_start;
extern unsigned char _binary_resources_sfo_icon_png_start;
extern unsigned char _binary_resources_text_icon_png_start;
extern unsigned char _binary_resources_ftp_png_start;
extern unsigned char _binary_resources_battery_png_start;
extern unsigned char _binary_resources_battery_bar_red_png_start;
extern unsigned char _binary_resources_battery_bar_green_png_start;
extern unsigned char _binary_resources_battery_bar_charge_png_start;
INCLUDE_EXTERN_RESOURCE(colors_txt);
INCLUDE_EXTERN_RESOURCE(colors_txt_size);
extern unsigned char _binary_resources_colors_txt_start;
extern unsigned char _binary_resources_colors_txt_size;
INCLUDE_EXTERN_RESOURCE(folder_icon_png);
INCLUDE_EXTERN_RESOURCE(file_icon_png);
INCLUDE_EXTERN_RESOURCE(archive_icon_png);
INCLUDE_EXTERN_RESOURCE(image_icon_png);
INCLUDE_EXTERN_RESOURCE(audio_icon_png);
INCLUDE_EXTERN_RESOURCE(sfo_icon_png);
INCLUDE_EXTERN_RESOURCE(text_icon_png);
INCLUDE_EXTERN_RESOURCE(ftp_png);
INCLUDE_EXTERN_RESOURCE(battery_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_red_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_green_png);
INCLUDE_EXTERN_RESOURCE(battery_bar_charge_png);
INCLUDE_EXTERN_RESOURCE(cover_png);
INCLUDE_EXTERN_RESOURCE(play_png);
INCLUDE_EXTERN_RESOURCE(pause_png);
INCLUDE_EXTERN_RESOURCE(fastforward_png);
INCLUDE_EXTERN_RESOURCE(fastrewind_png);
// Shell colors
int BACKGROUND_COLOR;
@ -84,10 +90,20 @@ int TEXT_HIGHLIGHT_COLOR;
// Photo viewer colors
int PHOTO_ZOOM_COLOR;
// Audio player colors
int AUDIO_INFO_ASSIGN;
int AUDIO_INFO;
int AUDIO_SPEED;
int AUDIO_TIME_CURRENT;
int AUDIO_TIME_SLASH;
int AUDIO_TIME_TOTAL;
int AUDIO_TIME_BAR;
int AUDIO_TIME_BAR_BG;
vita2d_texture *folder_icon = NULL, *file_icon = NULL, *archive_icon = NULL, *image_icon = NULL, *audio_icon = NULL, *sfo_icon = NULL, *text_icon = NULL,
*ftp_image = NULL, *dialog_image = NULL, *context_image = NULL, *context_more_image = NULL, *battery_image = NULL, *battery_bar_red_image = NULL,
*battery_bar_green_image = NULL, *battery_bar_charge_image = NULL, *bg_browser_image = NULL, *bg_hex_image = NULL,
*bg_text_image = NULL, *bg_photo_image = NULL;
*bg_text_image = NULL, *bg_photo_image = NULL, *cover_image = NULL, *play_image = NULL, *pause_image = NULL, *fastforward_image = NULL, *fastrewind_image = NULL;
vita2d_texture *wallpaper_image[MAX_WALLPAPERS];
@ -143,6 +159,16 @@ void loadTheme() {
// Photo viewer colors
COLOR_ENTRY(PHOTO_ZOOM_COLOR),
// Audio player colors
COLOR_ENTRY(AUDIO_INFO_ASSIGN),
COLOR_ENTRY(AUDIO_INFO),
COLOR_ENTRY(AUDIO_SPEED),
COLOR_ENTRY(AUDIO_TIME_CURRENT),
COLOR_ENTRY(AUDIO_TIME_SLASH),
COLOR_ENTRY(AUDIO_TIME_TOTAL),
COLOR_ENTRY(AUDIO_TIME_BAR),
COLOR_ENTRY(AUDIO_TIME_BAR_BG),
};
// Load default config file
@ -223,6 +249,21 @@ void loadTheme() {
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/bg_photoviewer.png", theme_name);
bg_photo_image = vita2d_load_PNG_file(path);
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/cover.png", theme_name);
cover_image = vita2d_load_PNG_file(path);
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/play.png", theme_name);
play_image = vita2d_load_PNG_file(path);
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/pause.png", theme_name);
pause_image = vita2d_load_PNG_file(path);
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/fastforward.png", theme_name);
fastforward_image = vita2d_load_PNG_file(path);
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/fastrewind.png", theme_name);
fastrewind_image = vita2d_load_PNG_file(path);
// Wallpapers
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/theme/%s/wallpaper.png", theme_name);
vita2d_texture *image = vita2d_load_PNG_file(path);
@ -320,4 +361,19 @@ void loadTheme() {
if (!battery_bar_charge_image)
battery_bar_charge_image = vita2d_load_PNG_buffer(&_binary_resources_battery_bar_charge_png_start);
if (!cover_image)
cover_image = vita2d_load_PNG_buffer(&_binary_resources_cover_png_start);
if (!play_image)
play_image = vita2d_load_PNG_buffer(&_binary_resources_play_png_start);
if (!pause_image)
pause_image = vita2d_load_PNG_buffer(&_binary_resources_pause_png_start);
if (!fastforward_image)
fastforward_image = vita2d_load_PNG_buffer(&_binary_resources_fastforward_png_start);
if (!fastrewind_image)
fastrewind_image = vita2d_load_PNG_buffer(&_binary_resources_fastrewind_png_start);
}

15
theme.h
View File

@ -67,9 +67,20 @@ extern int TEXT_HIGHLIGHT_COLOR;
// Photo viewer colors
extern int PHOTO_ZOOM_COLOR;
// Audio player colors
extern int AUDIO_INFO_ASSIGN;
extern int AUDIO_INFO;
extern int AUDIO_SPEED;
extern int AUDIO_TIME_CURRENT;
extern int AUDIO_TIME_SLASH;
extern int AUDIO_TIME_TOTAL;
extern int AUDIO_TIME_BAR;
extern int AUDIO_TIME_BAR_BG;
extern vita2d_texture *folder_icon, *file_icon, *archive_icon, *image_icon, *audio_icon, *sfo_icon, *text_icon,
*ftp_image, *dialog_image, *context_image, *context_more_image, *battery_image, *battery_bar_red_image, *battery_bar_green_image,
*battery_bar_charge_image, *bg_browser_image, *bg_hex_image, *bg_text_image, *bg_photo_image;
*ftp_image, *dialog_image, *context_image, *context_more_image, *battery_image, *battery_bar_red_image,
*battery_bar_green_image, *battery_bar_charge_image, *bg_browser_image, *bg_hex_image, *bg_text_image,
*bg_photo_image, *cover_image, *play_image, *pause_image, *fastforward_image, *fastrewind_image;
extern vita2d_texture *wallpaper_image[MAX_WALLPAPERS];
extern vita2d_texture *previous_wallpaper_image, *current_wallpaper_image;