Really? I could've sworn that's where I got it from... :p I need more sleep!
OK, basically it's two files; wave.c and wave.h - both seem to be derived from the pre-SDK sound.c however I am noticing that not everything is implemented (looping is a good example).
Code: Select all
#define PGA_CHANNELS 3
#define PGA_SAMPLES 256
#define MAXVOLUME 0x8000
#define SND1_MAXSLOT 16
#define PB_N 32
#define WAVFILEMAX_BG 8*1024*1024
#define O_RDONLY 0x0001
#define O_WRONLY 0x0002
#define O_RDWR 0x0003
#define O_NBLOCK 0x0010
#define O_APPEND 0x0100
#define O_CREAT 0x0200
#define O_TRUNC 0x0400
#define O_NOWAIT 0x8000
#define MAX_PATH 512
#define NULL 0
//---------- variables
int pga_ready=0;
int pga_handle[PGA_CHANNELS];
short pga_sndbuf[PGA_CHANNELS][2][PGA_SAMPLES][2];
int pga_threadhandle[PGA_CHANNELS];
volatile int pga_terminate=0;
typedef int (*pg_threadfunc_t)(int args, void *argp);
typedef struct {
unsigned long channels;
unsigned long samplerate;
unsigned long samplecount;
unsigned long datalength;
char *wavdata;
unsigned long rateratio; // samplerate / 44100 * 0x10000
unsigned long playptr;
unsigned long playptr_frac;
int playloop;
} wavout_wavinfo_t;
wavout_wavinfo_t *wavout_snd0_wavinfo=0;
wavout_wavinfo_t wavout_snd1_wavinfo[SND1_MAXSLOT];
int wavout_snd1_playing[SND1_MAXSLOT];
int wavout_snd0_ready=0;
unsigned long wavout_snd0_playptr=0;
int wavout_snd0_playend=0;
short powerbuf[PB_N][256];
unsigned int powerbuf_in=0;
short powersrc[256];
short powersrc2[256];
char wavdata_bg[WAVFILEMAX_BG];
wavout_wavinfo_t wavinfo_bg;
char pg_mypath[MAX_PATH];
char pg_workdir[MAX_PATH];
//------------ Tableau de merde
int brtbl[]={
0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240, 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248,
4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244, 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252,
2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242, 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250,
6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246, 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254,
1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241, 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249,
5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245, 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253,
3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243, 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251,
7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247, 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255,
};
int mm1[8][128]={
{ 16384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 11585, 0,-11585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 15136, 11585, 6269, 0, -6269,-11585,-15136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 16069, 15136, 13622, 11585, 9102, 6269, 3196, 0, -3196, -6269, -9102,-11585,-13622,-15136,-16069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 16305, 16069, 15678, 15136, 14449, 13622, 12665, 11585, 10393, 9102, 7723, 6269, 4756, 3196, 1605, 0, -1605, -3196, -4756, -6269, -7723, -9102,-10393,-11585,-12665,-13622,-14449,-15136,-15678,-16069,-16305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 16364, 16305, 16206, 16069, 15892, 15678, 15426, 15136, 14810, 14449, 14053, 13622, 13159, 12665, 12139, 11585, 11002, 10393, 9759, 9102, 8423, 7723, 7005, 6269, 5519, 4756, 3980, 3196, 2404, 1605, 803, 0, -803, -1605, -2404, -3196, -3980, -4756, -5519, -6269, -7005, -7723, -8423, -9102, -9759,-10393,-11002,-11585,-12139,-12665,-13159,-13622,-14053,-14449,-14810,-15136,-15426,-15678,-15892,-16069,-16206,-16305,-16364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 16384, 16379, 16364, 16339, 16305, 16260, 16206, 16142, 16069, 15985, 15892, 15790, 15678, 15557, 15426, 15286, 15136, 14978, 14810, 14634, 14449, 14255, 14053, 13842, 13622, 13395, 13159, 12916, 12665, 12406, 12139, 11866, 11585, 11297, 11002, 10701, 10393, 10079, 9759, 9434, 9102, 8765, 8423, 8075, 7723, 7366, 7005, 6639, 6269, 5896, 5519, 5139, 4756, 4369, 3980, 3589, 3196, 2801, 2404, 2005, 1605, 1205, 803, 402, 0, -402, -803, -1205, -1605, -2005, -2404, -2801, -3196, -3589, -3980, -4369, -4756, -5139, -5519, -5896, -6269, -6639, -7005, -7366, -7723, -8075, -8423, -8765, -9102, -9434, -9759,-10079,-10393,-10701,-11002,-11297,-11585,-11866,-12139,-12406,-12665,-12916,-13159,-13395,-13622,-13842,-14053,-14255,-14449,-14634,-14810,-14978,-15136,-15286,-15426,-15557,-15678,-15790,-15892,-15985,-16069,-16142,-16206,-16260,-16305,-16339,-16364,-16379, },
};
int mm2[8][128]={
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0,-16384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0,-11585,-16384,-11585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, -6269,-11585,-15136,-16383,-15136,-11585, -6269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, -3196, -6269, -9102,-11585,-13622,-15136,-16069,-16383,-16069,-15136,-13622,-11585, -9102, -6269, -3196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, -1605, -3196, -4756, -6269, -7723, -9102,-10393,-11585,-12665,-13622,-14449,-15136,-15678,-16069,-16305,-16384,-16305,-16069,-15678,-15136,-14449,-13622,-12665,-11585,-10393, -9102, -7723, -6269, -4756, -3196, -1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, -803, -1605, -2404, -3196, -3980, -4756, -5519, -6269, -7005, -7723, -8423, -9102, -9759,-10393,-11002,-11585,-12139,-12665,-13159,-13622,-14053,-14449,-14810,-15136,-15426,-15678,-15892,-16069,-16206,-16305,-16364,-16384,-16364,-16305,-16206,-16069,-15892,-15678,-15426,-15136,-14810,-14449,-14053,-13622,-13159,-12665,-12139,-11585,-11002,-10393, -9759, -9102, -8423, -7723, -7005, -6269, -5519, -4756, -3980, -3196, -2404, -1605, -803, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, -402, -803, -1205, -1605, -2005, -2404, -2801, -3196, -3589, -3980, -4369, -4756, -5139, -5519, -5896, -6269, -6639, -7005, -7366, -7723, -8075, -8423, -8765, -9102, -9434, -9759,-10079,-10393,-10701,-11002,-11297,-11585,-11866,-12139,-12406,-12665,-12916,-13159,-13395,-13622,-13842,-14053,-14255,-14449,-14634,-14810,-14978,-15136,-15286,-15426,-15557,-15678,-15790,-15892,-15985,-16069,-16142,-16206,-16260,-16305,-16339,-16364,-16379,-16384,-16379,-16364,-16339,-16305,-16260,-16206,-16142,-16069,-15985,-15892,-15790,-15678,-15557,-15426,-15286,-15136,-14978,-14810,-14634,-14449,-14255,-14053,-13842,-13622,-13395,-13159,-12916,-12665,-12406,-12139,-11866,-11585,-11297,-11002,-10701,-10393,-10079, -9759, -9434, -9102, -8765, -8423, -8075, -7723, -7366, -7005, -6639, -6269, -5896, -5519, -5139, -4756, -4369, -3980, -3589, -3196, -2801, -2404, -2005, -1605, -1205, -803, -402, },
};
const unsigned char sqrtbl[]={
0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
};
//---------- proto
int pgaInit();
void (*pga_channel_callback[PGA_CHANNELS])(void *buf, unsigned long reqn);
static int pga_channel_thread(int args, void *argp);
void pga_channel_thread_callback(int channel, void *buf, unsigned long reqn);
void pgaSetChannelCallback(int channel, void *callback);
int pgaOutBlocking(unsigned long channel,unsigned long vol1,unsigned long vol2,void *buf);
static void wavout_snd0_callback(short *_buf, unsigned long _reqn);
static void wavout_snd1_callback(short *_buf, unsigned long _reqn);
void powercalc(short *in);
unsigned long sqri(unsigned long d);
int wavoutLoadWav(const char *filename, wavout_wavinfo_t *wi, void *buf, unsigned long buflen);
int pgfOpen(const char *filename, unsigned long flag);
void pgfClose(int fd);
int pgfRead(int fd, void *data, int size);
void wavoutStopPlay0();
void wavoutStartPlay0(wavout_wavinfo_t *wi);
//---------- function
int pgaInit()
{
int i,ret;
int failed=0;
char str[32];
pga_terminate=0;
pga_ready=0;
for (i=0; i<PGA_CHANNELS; i++) {
pga_handle[i]=-1;
pga_threadhandle[i]=-1;
pga_channel_callback[i]=0;
}
for (i=0; i<PGA_CHANNELS; i++) {
if ((pga_handle[i]=sceAudio_3(-1,PGA_SAMPLES,0))<0) failed=1;
}
if (failed) {
for (i=0; i<PGA_CHANNELS; i++) {
if (pga_handle[i]!=-1) sceAudio_4(pga_handle[i]);
pga_handle[i]=-1;
}
return -1;
}
pga_ready=1;
strcpy(str,"pgasnd0");
for (i=0; i<PGA_CHANNELS; i++) {
str[6]='0'+i;
pga_threadhandle[i]=sceKernelCreateThread(str,(pg_threadfunc_t)&pga_channel_thread,0x12,0x10000,0,NULL);
if (pga_threadhandle[i]<0) {
pga_threadhandle[i]=-1;
failed=1;
break;
}
ret=sceKernelStartThread(pga_threadhandle[i],sizeof(i),&i);
if (ret!=0) {
failed=1;
break;
}
}
if (failed) {
pga_terminate=1;
for (i=0; i<PGA_CHANNELS; i++) {
if (pga_threadhandle[i]!=-1) {
sceKernelWaitThreadEnd(pga_threadhandle[i],NULL);
sceKernelDeleteThread(pga_threadhandle[i]);
}
pga_threadhandle[i]=-1;
}
pga_ready=0;
return -1;
}
return 0;
}
static int pga_channel_thread(int args, void *argp)
{
volatile int bufidx=0;
int channel=*(int *)argp;
while (pga_terminate==0) {
void *bufptr=&pga_sndbuf[channel][bufidx];
void (*callback)(void *buf, unsigned long reqn);
callback=pga_channel_callback[channel];
if (callback) {
callback(bufptr,PGA_SAMPLES);
} else {
unsigned long *ptr=bufptr;
int i;
for (i=0; i<PGA_SAMPLES; ++i) *(ptr++)=0;
}
pgaOutBlocking(channel,0x8000,0x8000,bufptr);
bufidx=(bufidx?0:1);
}
sceKernelExitThread(0);
return 0;
}
void pga_channel_thread_callback(int channel, void *buf, unsigned long reqn)
{
void (*callback)(void *buf, unsigned long reqn);
callback=pga_channel_callback[channel];
}
void pgaSetChannelCallback(int channel, void *callback)
{
pga_channel_callback[channel]=callback;
}
int pgaOutBlocking(unsigned long channel,unsigned long vol1,unsigned long vol2,void *buf)
{
if (!pga_ready) return -1;
if (channel>=PGA_CHANNELS) return -1;
if (vol1>MAXVOLUME) vol1=MAXVOLUME;
if (vol2>MAXVOLUME) vol2=MAXVOLUME;
return sceAudio_2(pga_handle[channel],vol1,vol2,buf);
}
int wavoutInit()
{
int i;
wavout_snd0_wavinfo=0;
for (i=0; i<SND1_MAXSLOT; i++) {
wavout_snd1_playing[i]=0;
}
pgaSetChannelCallback(0,wavout_snd0_callback);
pgaSetChannelCallback(1,wavout_snd1_callback);
return 0;
}
static void wavout_snd0_callback(short *_buf, unsigned long _reqn)
{
static int power[128];
unsigned long i;
unsigned long ptr,frac,rr,max;
int channels;
char *src;
short *buf=_buf;
unsigned long reqn=_reqn;
wavout_wavinfo_t *wi=wavout_snd0_wavinfo;
if (wi==0) {
wavout_snd0_ready=1;
memset(buf,0,reqn*4);
return;
}
wavout_snd0_ready=0;
ptr=wi->playptr;
frac=wi->playptr_frac;
rr=wi->rateratio;
max=wi->samplecount;
channels=wi->channels;
src=wi->wavdata;
for (; reqn>0; --reqn) {
frac+=rr;
ptr+=(frac>>16);
frac&=0xffff;
if (ptr>=max) {
if (wi->playloop) {
ptr=0;
} else {
for (; reqn>0; --reqn) {
*(buf++)=0;
*(buf++)=0;
}
goto playend;
}
}
if (channels==1) {
buf[0]=buf[1]=*(short *)(src+ptr*2);
buf+=2;
} else {
buf[0]=*(short *)(src+ptr*4);
buf[1]=*(short *)(src+ptr*4+2);
buf+=2;
}
}
powercalc(_buf); //’P‚Éwave‚ð�o‚·‚¾‚¯‚È‚ç•s—v
wavout_snd0_playptr=ptr;
wi->playptr=ptr;
wi->playptr_frac=frac;
return;
playend:
wavout_snd0_playend=1;
return;
}
static void wavout_snd1_callback(short *_buf, unsigned long _reqn)
{
unsigned long i,slot;
wavout_wavinfo_t *wi;
unsigned long ptr,frac;
short *buf=_buf;
for (i=0; i<_reqn; i++) {
int outr=0,outl=0;
for (slot=0; slot<SND1_MAXSLOT; slot++) {
if (!wavout_snd1_playing[slot]) continue;
wi=&wavout_snd1_wavinfo[slot];
frac=wi->playptr_frac+wi->rateratio;
wi->playptr=ptr=wi->playptr+(frac>>16);
wi->playptr_frac=(frac&0xffff);
if (ptr>=wi->samplecount) {
wavout_snd1_playing[slot]=0;
break;
}
short *src=(short *)wi->wavdata;
if (wi->channels==1) {
outl+=src[ptr];
outr+=src[ptr];
} else {
outl+=src[ptr*2];
outr+=src[ptr*2+1];
}
}
if (outl<-32768) outl=-32768;
else if (outl>32767) outl=32767;
if (outr<-32768) outr=-32768;
else if (outr>32767) outr=32767;
*(buf++)=outl;
*(buf++)=outr;
}
}
unsigned long sqri(unsigned long d)
{
unsigned char c;
unsigned long r;
if (d==0) return 0;
r= (c=sqrtbl[((unsigned char *)&d)[3]])?((unsigned long)c<<12):(
(c=sqrtbl[((unsigned char *)&d)[2]])?((unsigned long)c<<8):(
(c=sqrtbl[((unsigned char *)&d)[1]])?((unsigned long)c<<4):(
sqrtbl[((unsigned char *)&d)[0]] )));
r=(d/r+r)>>1;
r=(d/r+r)>>1;
r=(d/r+r)>>1;
r=(d/r+r)>>1;
return r;
}
void powercalc(short *in)
{
{//work with sources
int i,j,sum;
for (i=0; i<256-16; i++) powersrc[i]=powersrc[i+16];
sum=0;
for (i=0; i<16; i++) {
powersrc[256-16+i]=( (int)in[i*32]+(int)in[i*32+8]+(int)in[i*32+16]+(int)in[i*32+24] )/4;
}
}
{
int i;
for (i=0; i<256; i++) powersrc2[i]=powersrc[i];
for (i=0; i<32; i++) {
powersrc2[i]=((int)powersrc2[i])*i/32;
powersrc2[255-i]=((int)powersrc2[255-i])*i/32;
}
}
long m=8;
long n=256;
long m1,m2;
long i,i1,j,k,i2,l,l1,l2;
int ix[256],iy[256];
int tx,ty,pw;
//shuffle
for (i=0; i<256; i++) {
ix[i]=(int)(powersrc2[brtbl[i]]>>1);
iy[i]=0;
}
//fft main
l2 = 1;
for (l=0; l<8; l++) {
l1 = l2;
l2 <<= 1;
for (j=0; j<l1; j++) {
m1=mm1[l][j]/64;
m2=mm2[l][j]/64;
for (i=j; i<n; i+=l2) {
i1 = i + l1;
tx = ( m1 * ix[i1] - m2 * iy[i1] )/256;
ty = ( m1 * iy[i1] + m2 * ix[i1] )/256;
ix[i1] = ix[i] - tx;
iy[i1] = iy[i] - ty;
ix[i] += tx;
iy[i] += ty;
}
}
}
//scale & normalize
short *pp=powerbuf[powerbuf_in];
for (i=0; i<128; i++) {
//tx,ty : re,im forward fft scaling=256, fixed point +-16384
tx=ix[i]/256;
ty=iy[i]/256;
pw=(sqri(tx*tx+ty*ty));
//normalize it
pw=pw*(j+8)/512;
if (pw>127) pw=127;
*(pp++)=pw;
}
powerbuf_in=((powerbuf_in+1)&(PB_N-1));
return;
}
int wavoutLoadWav(const char *filename, wavout_wavinfo_t *wi, void *buf, unsigned long buflen)
{
unsigned int filelen;
int fd;
unsigned long channels;
unsigned long samplerate;
unsigned long blocksize;
unsigned long bitpersample;
unsigned long datalength;
unsigned long samplecount;
unsigned long i;
char *wavfile=buf;
wi->wavdata=NULL;
fd=pgfOpen(filename,O_RDONLY);
if (fd<0) return -1;
filelen=pgfRead(fd,wavfile,buflen);
pgfClose(fd);
if (filelen>=buflen) {
//too long
return -1;
}
if (memcmp(wavfile,"RIFF",4)!=0) {
// pgcPuts("format err");
return -1;
}
if (memcmp(wavfile+8,"WAVEfmt \x10\x00\x00\x00\x01\x00",14)!=0) {
// pgcPuts("format err");
return -1;
}
channels=*(short *)(wavfile+0x16);
samplerate=*(long *)(wavfile+0x18);
blocksize=*(short *)(wavfile+0x20);
bitpersample=*(short *)(wavfile+0x22);
if (memcmp(wavfile+0x24,"data",4)!=0) {
// pgcPuts("format err");
return -1;
}
datalength=*(unsigned long *)(wavfile+0x28);
if (datalength+0x2c>filelen) {
// pgcPuts("format err");
return -1;
}
if (channels!=2 && channels!=1) {
// pgcPuts("format err, channel");
return -1;
}
// if (samplerate!=44100 && samplerate!=22050 && samplerate!=11025) {
if (samplerate>100000 || samplerate<2000) {
// pgcPuts("format err, samplerate");
return -1;
}
if (blocksize!=channels*2) {
// pgcPuts("format err, blocksize");
return -1;
}
if (bitpersample!=16) {
// pgcPuts("format err, bitpersample");
return -1;
}
if (channels==2) {
samplecount=datalength/4;
} else {
samplecount=datalength/2;
}
if (samplecount<=0) {
// pgcPuts("format err, samplecount");
return -1;
}
wi->channels=channels;
wi->samplerate=samplerate;
wi->samplecount=samplecount;
wi->datalength=datalength;
wi->wavdata=wavfile+0x2c;
wi->rateratio=(samplerate*0x4000)/11025;
wi->playptr=0;
wi->playptr_frac=0;
wi->playloop=0;
return 0;
}
int pgfOpen(const char *filename, unsigned long flag)
{
char fn[MAX_PATH*2];
if (strchr(filename,':')!=NULL || *filename=='/' || *filename=='\\') {
return sceIoOpen(filename,flag);
} else {
strcpy(fn,pg_workdir);
strcat(fn,filename);
return sceIoOpen(fn,flag);
}
}
void pgfClose(int fd)
{
sceIoClose(fd);
}
int pgfRead(int fd, void *data, int size)
{
return sceIoRead(fd,data,size);
}
void wavoutStopPlay0()
{
if (wavout_snd0_wavinfo!=0) {
while (wavout_snd0_ready) sceDisplayWaitVblankStart();;
wavout_snd0_wavinfo=0;
while (!wavout_snd0_ready) sceDisplayWaitVblankStart();;
}
}
void wavoutStartPlay0(wavout_wavinfo_t *wi)
{
wavoutStopPlay0();
while (!wavout_snd0_ready) sceDisplayWaitVblankStart();;
wavout_snd0_playptr=0;
wavout_snd0_playend=0;
wavout_snd0_wavinfo=wi;
while (wavout_snd0_ready) sceDisplayWaitVblankStart();;
}
ok, so from the source's wave.c and sound.c you can see that the looping part within the wavout_snd?_callback function is lacking in wave.c - I attempted adding checks - resetting ptr = 0 etc like in sound.c but that doesn't help...I also attempted to add "is_playing" to the wavinfo struct but i think i messed up as that just caused the same wav to play overlapped over all the channels/slots but still died after one iteration of playing it... time to go to work!