Page 1 of 2

libsd.irx?

Posted: Sat Jul 01, 2006 7:05 pm
by Kojima
I'm trying to add some music to my game using the ps2snd demo as a template, but it loads two irx files from the host side. One, ps2snd.irx i found in the iop folder, but the other, libsd.irx was nowhere to be found.
Any clues?

I did do a forum search but for some reason it won't let me search for a single word "Libsd.irx" it keeps tokenizing it and searching for libsd and irx seperately.

Posted: Sat Jul 01, 2006 7:14 pm
by Kojima
Got it to work by loading it from the rom \/
ret = SifLoadModule("rom0:LIBSD", 0, NULL);

Any reason why the ps2sdk demo uses a irx thats not included with the package or is just my precompiled package that doesn't have it? (I'd prefer to use it host side since not all rom versions have libsd according to one post i read)

Posted: Sat Jul 01, 2006 7:22 pm
by Kojima
Now it's refusing to link properly.
I've added -lps2snd.a and -lc as does the ps2snd demo but it bulks on,
SdSetParam(0 | SD_PARAM_MVOLL, 0x3fff);
SdSetParam(0 | SD_PARAM_MVOLR, 0x3fff);
SdSetParam(1 | SD_PARAM_MVOLL, 0x3fff);
SdSetParam(1 | SD_PARAM_MVOLR, 0x3fff);

IT compiles fine though, so no missing includes.

Posted: Sat Jul 01, 2006 8:25 pm
by evilo
The LIBSD irx is contained in the PS2 rom.

beware that early japanese version don't include it, so you should prefer using FREESD instead (LIBS replacement included in the PS2SDK).

jbit will confirm it, but it should be compatible with his ps2snd library.

Posted: Sat Jul 01, 2006 9:13 pm
by Kojima
Ok thanks I'll switch over then.

While you're about d'you have any idea why it isn't linking? I'd appreciate any advice you could give, I'm stomped :)

Posted: Sat Jul 01, 2006 11:31 pm
by Kojima
Well I've tried just about everything, even copied over the ps2snd make file word for word to mine in case it was a makefile issue.

Here's my full source, it's all single source and everything runs perfectly except the four calls to the sound lib to set the volume, which do not link.(And when i say everything elses runs perfectly i of course mean when i cut the four offending lines)


(Btw if this post is too big for the server lemme know and i'll remove it)

Code: Select all


#include "gsKit.h"
#include "dmaKit.h"
#include "malloc.h"
#include "libpad.h"
#include "kernel.h"
#include "stdio.h"
#include "loadfile.h"
#include <sifrpc.h>
#include <ps2snd.h>

typedef char int8;
typedef short int16;
typedef int int32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef long int64;
typedef struct int128
&#123;
int64 lo, hi;
&#125; int128 __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41;;
typedef struct uint128
&#123;
uint64 lo, hi;
&#125; uint128 __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41;;

uint64 MakeRgb&#40;int r,int g,int b&#41;
&#123;
	return &#40;&#40;uint64&#41;&#40;r&#41; <<0&#41; | &#40;&#40;uint64&#41;&#40;g&#41; << 8&#41; | &#40;&#40;uint64&#41;&#40;b&#41; << 16&#41;;
&#125;

uint64 MakeRgba&#40;int r,int g,int b,int a&#41;
&#123;
		return &#40;&#40;uint64&#41;&#40;r&#41; <<0&#41; | &#40;&#40;uint64&#41;&#40;g&#41; << 8&#41; | &#40;&#40;uint64&#41;&#40;b&#41; << 16&#41; | &#40;&#40;uint64&#41;&#40;a&#41; << 32&#41;;
&#125;

template <class T>
class ListNode
&#123;

public&#58;
    T &get&#40;&#41;
    &#123;
        return object;
    &#125;;
    void set&#40;T &object&#41;
    &#123;
        this->object = object;
    &#125;;

    ListNode<T> *getNext&#40;&#41;
    &#123;
        return nextNode;
    &#125;;
    void setNext&#40;ListNode<T> *nextNode&#41;
    &#123;
        this->nextNode = nextNode;
    &#125;;

private&#58;
    T object;
    ListNode<T> *nextNode;
&#125;;

template <class T>
class List
&#123;

public&#58;
    // Constructor
    List&#40;&#41;
    &#123;
        headNode = new ListNode<T>;
        headNode->setNext&#40;NULL&#41;;

        currentNode = NULL;
        size = 0;
    &#125;;

    // Destructor
    ~List&#40;&#41;
    &#123;

        ListNode<T> *pointerToDelete, *pointer = headNode;

        while &#40;pointer != NULL&#41;
        &#123;
            pointerToDelete = pointer;
            pointer = pointer->getNext&#40;&#41;;
            delete pointerToDelete;
        &#125;
    &#125;;

    T &get&#40;&#41;
    &#123;

        if &#40;currentNode == NULL&#41;
            start&#40;&#41;;

        return currentNode->get&#40;&#41;
               ;
    &#125;;

    void add&#40;T &addObject&#41;
    &#123;

        ListNode<T> *newNode = new ListNode<T>;

        newNode->set&#40;addObject&#41;
        ;

        newNode->setNext&#40;headNode->getNext&#40;&#41;&#41;;
        headNode->setNext&#40;newNode&#41;;

        size++;
    &#125;;

    void remove&#40;&#41;
    &#123;

        lastCurrentNode->setNext&#40;currentNode->getNext&#40;&#41;&#41;;

        delete currentNode;

        currentNode = lastCurrentNode;

        size--;
    &#125;;

    void start&#40;&#41;
    &#123;
        lastCurrentNode = headNode;
        currentNode = headNode;
    &#125;;

    bool next&#40;&#41;
    &#123;

        // If the currentNode now points at nothing, we've reached the end
        if &#40;currentNode == NULL&#41;
            return false;

        // Update the last node and current node
        lastCurrentNode = currentNode;
        currentNode = currentNode->getNext&#40;&#41;;

        // If currentNode points at nothing or there is nothing added, we can immediately return false
        if &#40;currentNode == NULL || size == 0&#41;
            return false;
        else
            return true;
    &#125;;

    int getSize&#40;&#41;
    &#123;
        return size;
    &#125;;

private&#58;
    int size;
    ListNode<T> *headNode;
    ListNode<T> *currentNode, *lastCurrentNode;
&#125;;


extern "C"
&#123;
void UpdatePad&#40;&#41;
&#123;
	int i=0;
	int ret=0;
	int port=0,slot=0;
	ret=padGetState&#40;port, slot&#41;;
  while&#40;&#40;ret != PAD_STATE_STABLE&#41; && &#40;ret != PAD_STATE_FINDCTP1&#41;&#41; &#123;
  			if&#40;ret==PAD_STATE_DISCONN&#41; &#123;
            printf&#40;"Pad&#40;%d, %d&#41; is disconnected\n", port, slot&#41;;
        &#125;
        ret=padGetState&#40;port, slot&#41;;
       &#125;
       if&#40;i==1&#41; &#123;
           printf&#40;"Pad&#58; OK!\n"&#41;;
       &#125;
            
&#125;

struct padButtonStatus buttons;
u32 paddata;
u32 old_pad = 0;
u32 new_pad;
int but_select,but_start;
int but_cross,but_circle,but_square,but_triangle;
float but_crossp,but_circlep,but_squarep,but_trianglep;
int but_l1,but_l2,but_r1,but_r2;
int but_l3,but_r3;
float but_l1p,but_l2p,but_r1p,but_r2p;
float joy_lx,joy_ly;
float joy_rx,joy_ry;
float joy_hx,joy_hy;

void ReadPad&#40;&#41;
&#123;
	int ret;
	int port = 0,slot =0;
	but_square=0;
	but_triangle=0;
	but_circle=0;
	but_cross=0;
	but_l1=0;
	but_l2=0;
	but_r1=0;
	but_r2=0;
	but_select=0;
	but_start=0;
	but_l3=0;
	but_r3=0;
	
	ret = padRead&#40;port, slot, &buttons&#41;;	
	if &#40;ret != 0&#41; &#123;
            paddata = 0xffff ^ buttons.btns;
                
            new_pad = paddata;//'paddata & ~old_pad;
            old_pad = paddata;
                             
            // Directions
            if&#40;new_pad & PAD_LEFT&#41; &#123;
                joy_hx = -1;
            &#125;
            if&#40;new_pad & PAD_DOWN&#41; &#123;
                joy_hy = 1;
            &#125;
            if&#40;new_pad & PAD_RIGHT&#41; &#123;
                joy_hx = 1;
            &#125;
            if&#40;new_pad & PAD_UP&#41; &#123;
                joy_hy = 1;
            &#125;
            if&#40;new_pad & PAD_START&#41; &#123;
                but_start = 1;
            &#125;
            if&#40;new_pad & PAD_R3&#41; &#123;
                but_r3 = 1;
            &#125;
            if&#40;new_pad & PAD_L3&#41; &#123;
                but_l3 = 1;
            &#125;
            if&#40;new_pad & PAD_SELECT&#41; &#123;
             		but_select = 1; 
             &#125;
            if&#40;new_pad & PAD_SQUARE&#41; &#123;
                but_square = 1;
            &#125;
            if&#40;new_pad & PAD_CROSS&#41; &#123;
              
                but_cross = 1;
            &#125;
            if&#40;new_pad & PAD_CIRCLE&#41; &#123;
             
                but_circle = 1;
            &#125;
            if&#40;new_pad & PAD_TRIANGLE&#41; &#123;
                but_triangle = 1;
            &#125;
            if&#40;new_pad & PAD_R1&#41; &#123;
          
                but_r1 = 1;
            &#125;
            if&#40;new_pad & PAD_L1&#41; &#123;
                     
                but_l1 = 1;
            &#125;
            if&#40;new_pad & PAD_R2&#41; &#123;
                but_r2 = 1;
            &#125;
            if&#40;new_pad & PAD_L2&#41; &#123;
                but_l2 = 1;
            &#125;
            but_crossp = buttons.cross_p;
            but_squarep = buttons.square_p;
            but_circlep = buttons.circle_p;
            but_trianglep = buttons.triangle_p;
            but_l1p = buttons.l1_p;
            but_r1p = buttons.r1_p;
            but_l2p = buttons.l2_p;
            but_r2p = buttons.r2_p;
      			joy_hx -= buttons.left_p;
      			joy_hx += buttons.right_p;
      			joy_hy -= buttons.up_p;
      			joy_hy += buttons.down_p;
      			               
        &#125; 
&#125;

int waitPadReady&#40;int port, int slot&#41;
&#123;
    int state;
    int lastState;
    char stateString&#91;16&#93;;

    state = padGetState&#40;port, slot&#41;;
    lastState = -1;
    while&#40;&#40;state != PAD_STATE_STABLE&#41; && &#40;state != PAD_STATE_FINDCTP1&#41;&#41; &#123;
        if &#40;state != lastState&#41; &#123;
            padStateInt2String&#40;state, stateString&#41;;
            printf&#40;"Please wait, pad&#40;%d,%d&#41; is in state %s\n", 
                       port, slot, stateString&#41;;
        &#125;
        lastState = state;
        state=padGetState&#40;port, slot&#41;;
    &#125;
    // Were the pad ever 'out of sync'?
    if &#40;lastState != -1&#41; &#123;
        printf&#40;"Pad OK!\n"&#41;;
    &#125;
    return 0;
&#125;

&#125;

u64 cur_col;

GSGLOBAL *gs_Global;


inline void SetColor&#40;int r,int g,int b,int a=255&#41;
&#123;
	cur_col = MakeRgba&#40;r,g,b,a&#41;; ;//GS_SETREG_RGBAQ&#40;r,g,b,a,0&#41;;
&#125;

inline void DrawRect&#40;float x,float y,float w,float h,int z&#41;
&#123;
	gsKit_prim_sprite&#40;gs_Global, x,y, x+w,y+h, z, cur_col &#41;;
&#125;

//consts instead of enum 'cos they wern't compiling for some reason.
const int Control_Pad = 1,Control_AI = 2;


class Bat
&#123;
public&#58;
	Bat&#40;float x,float y,int control&#41;
	&#123;
		_x=x;
		_y=y;
		_yi=0;
		_len=90;
		_cpu = control;
		_lenInc=0;
	&#125;
	~Bat&#40;&#41;
	&#123;
	&#125;
	void Render&#40;&#41;
	&#123;
		_len +=_lenInc;
		DrawRect&#40;_x,_y-&#40;_len/2&#41;,20,_len,5&#41;;
		_len -=_lenInc;
	&#125;
	
	void Update&#40;&#41;
	&#123;
		switch&#40;_cpu&#41;
		&#123;
			case Control_Pad&#58;
					_lenInc = but_crossp * 0.2;
					//print'f&#40;"LenInc&#58; %f \n",_lenInc&#41;;
					if&#40;abs&#40;joy_hy&#41;>30&#41;
					_yi += joy_hy *0.02;
					
				break;
			case Control_AI&#58;
					
				break;
		&#125;
		_y += _yi;
		
		if&#40;_y<&#40; &#40;_len/2&#41;+&#40;_lenInc/2&#41;&#41; &#41; _y=&#40; &#40;_len/2&#41;+&#40;_lenInc/2&#41;&#41;;
		if&#40;_y>&#40;gs_Global->Height-&#40; &#40;_len/2&#41;+&#40;_lenInc/2&#41; &#41; &#41;&#41; 
			_y = &#40;gs_Global->Height-&#40; &#40;_len/2&#41;+&#40;_lenInc/2&#41; &#41; &#41;;
			
		_yi *= 0.95;
		
		
	&#125;;
	float _lenInc;
	float _x,_y;
	float _yi,_len;
	int _cpu;
&#125;;

class Star
&#123;
public&#58;
	Star&#40;float x,float y,float z&#41;
	&#123;
		_x = x;
		_y = y;
		_z = z;
		_lx = x;
	&#125;
	void Move&#40;float x&#41;
	&#123;
		_x +=&#40;x/&#40;255-_z&#41;&#41;;
		if&#40; _x<-10 &#41;
		&#123;
			_x=gs_Global->Width+10;
			_y=rand&#40;&#41;%gs_Global->Height;
			_z=rand&#40;&#41;%255;
			_lx = _x;
		&#125;
	&#125;
	float _x,_y,_z;
	float _lx;
&#125;;

class Ball
&#123;
public&#58;
	Ball&#40;float x,float y&#41;
	&#123;
		_x = x;
		_y = y;
	&#125;
	void Update&#40;&#41;
	&#123;
		_x+=_xi;
		_y+=_yi;
	&#125;
	void Render&#40;&#41;
	&#123;
		SetColor&#40;255,255,255,255&#41;;
		DrawRect&#40;_x-8,_y-8,16,16,1 &#41;;
	&#125;
	float _x,_y;
	float _xi,_yi;
			
&#125;;

Ball *ball;

void UpdateAndRenderBall&#40;&#41;
&#123;
	ball->Update&#40;&#41;;
	ball->Render&#40;&#41;;
&#125;

List<Star *>stars;
List<Bat *>bats;

void AddStar&#40;float x,float y,float z&#41;
&#123;
	Star *star = new Star&#40;x,y,z&#41;;
	stars.add&#40; star &#41;;
&#125;

void StarsUpdateAndRender&#40;&#41;
&#123;
	stars.start&#40;&#41;;
	while&#40; stars.next&#40;&#41; &#41;
	&#123;
		Star * star = stars.get&#40;&#41;;
		star->_lx = star->_x+2;
		star->Move&#40; -50 &#41;;
		//SetColor&#40; star->_z,star->_z,star->_z,255 &#41;;
		
		//DrawRect&#40; star->_x-2,star->_y-2,4,4,&#40;int&#41;&#40;255-star->_z&#41; &#41;;
		float xd;
		xd = star->_lx - star->_x;
		xd = xd *2;
		gsKit_prim_line&#40; gs_Global, star->_x,star->_y,star->_x+xd,star->_y,&#40;255-star->_z&#41;,MakeRgb&#40;star->_z,star->_z,star->_z&#41; &#41;;
	&#125;
	
&#125;



void AddBat&#40;float x,int control&#41;
&#123;
	Bat *bat = new Bat&#40;x,gs_Global->Height/2.0,control&#41;;
	bats.add&#40; bat &#41;;
&#125;

void RenderBats&#40;&#41;
&#123;
	bats.start&#40;&#41;;
	SetColor&#40;255,255,255,255&#41;;
	while&#40; bats.next&#40;&#41; &#41;
	&#123;
		Bat *bat = bats.get&#40;&#41;;
		bat->Render&#40;&#41;;
	&#125;
&#125;

void UpdateBats&#40;&#41;
&#123;
	bats.start&#40;&#41;;
	while&#40; bats.next&#40;&#41; &#41;
	&#123;
		Bat *bat = bats.get&#40;&#41;;
		bat->Update&#40;&#41;;
	&#125;
&#125;

extern "C" &#123;
int main&#40;int argc, char ** argv&#41; &#123;
	u64 White, Black, Red, Green, Blue, BlueTrans, RedTrans, GreenTrans, WhiteTrans;
//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_VGA_640_60&#41;; // VGA 640x480@60Hz

	//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_DTV_480P&#41;; // HTDV 480P
	//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_DTV_720P&#41;; // HTDV 720P
	//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_DTV_1080I&#41;; // HDTV 1080I Full Buffers
	//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_DTV_1080I_I&#41;; // HDTV 1080I Half Buffers
	SifInitRpc&#40;0&#41;; 
	SifLoadModule&#40;"rom0&#58;SIO2MAN", 0, NULL&#41;; 
	SifLoadModule&#40;"rom0&#58;PADMAN", 0, NULL&#41;;
	int ret;
	/* Load LibSD &#40;freesd will work too one day, I promise ;&#41; */
	ret = SifLoadModule&#40;"rom0&#58;LIBSD", 0, NULL&#41;;
	if &#40;ret<0&#41;
	&#123;
		printf&#40;"XXXXX failed to load host&#58;LIBSD.IRX &#40;%d&#41;\n", ret&#41;;
		return 0;
	&#125;

	/* Load ps2snd */
	ret = SifLoadModule&#40;"host&#58;ps2snd.irx", 0, NULL&#41;;
	if &#40;ret<0&#41;
	&#123;
		printf&#40;"XXXXX failed to load host&#58;ps2snd.irx &#40;%d&#41;\n", ret&#41;;
		return 0;
	&#125;

	SdSetParam&#40;0 | SD_PARAM_MVOLL, 0x3fff&#41;;
	SdSetParam&#40;0 | SD_PARAM_MVOLR, 0x3fff&#41;;
	SdSetParam&#40;1 | SD_PARAM_MVOLL, 0x3fff&#41;;
	SdSetParam&#40;1 | SD_PARAM_MVOLR, 0x3fff&#41;;

		
	printf&#40;"About to init pad. \n"&#41;;
	static char padBuf&#91;256&#93; __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41;;
	printf&#40;"Created structure \n"&#41;;
	padInit&#40;0&#41;; 	
	printf&#40;"Called padinit.\n"&#41;;
	if&#40;&#40;padPortOpen&#40;0, 0, padBuf&#41;&#41; == 0&#41; &#123; 
		printf&#40;"padOpenPort failed"&#41;; 
 		return 0;
 	&#125;
 	printf&#40;"Joypad Initialized"&#41;;
 	waitPadReady&#40;0,0&#41;;
	padSetMainMode&#40;0,0, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK&#41;;
	waitPadReady&#40;0,0&#41;;
	padEnterPressMode&#40;0,0&#41;;
	waitPadReady&#40;0,0&#41;;
	
   gs_Global = gsKit_init_global&#40;GS_MODE_PAL&#41;; // Full Buffers
//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_PAL_I&#41;; // NTSC Half Buffers

//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_NTSC&#41;; // NTSC Full Buffers
//	GSGLOBAL *gsGlobal = gsKit_init_global&#40;GS_MODE_NTSC_I&#41;; // NTSC Half Buffers

	// You can use these to turn off Z/Double Buffering. They are on by default.
	// gsGlobal->DoubleBuffering = GS_SETTING_OFF;
	// gsGlobal->ZBuffering = GS_SETTING_OFF;

	// This makes things look marginally better in half-buffer mode...
	// however on some CRT and all LCD, it makes a really horrible screen shake.
	// Uncomment this to disable it. &#40;It is on by default&#41;
	// gsGlobal->DoSubOffset = GS_SETTING_OFF;	

	gs_Global->PrimAlphaEnable = GS_SETTING_ON;	
	
	float x = 10;
	float y = 10;
	float width = 150;
	float height = 150;

	float VHeight;

	VHeight = gs_Global->Height;

	float *LineStrip;
	float *LineStripPtr;
	float *TriStrip;
	float *TriStripPtr;
	float *TriFanPtr;
	float *TriFan;

	
	dmaKit_init&#40;D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
		    D_CTRL_STD_OFF, D_CTRL_RCYC_8&#41;;

	// Initialize the DMAC
	dmaKit_chan_init&#40;DMA_CHANNEL_GIF&#41;;
	dmaKit_chan_init&#40;DMA_CHANNEL_FROMSPR&#41;;
	dmaKit_chan_init&#40;DMA_CHANNEL_TOSPR&#41;;

	White = GS_SETREG_RGBAQ&#40;0xFF,0xFF,0xFF,0x00,0x00&#41;;

	
	gsKit_init_screen&#40;gs_Global&#41;;
	gsKit_clear&#40;gs_Global, White&#41;;
	gsKit_set_test&#40;gs_Global, GS_ZTEST_OFF&#41;;
	gsKit_mode_switch&#40;gs_Global, GS_ONESHOT&#41;;
	
	//Init paddles
	
	AddBat&#40; 20,Control_Pad &#41;;
	AddBat&#40; gs_Global->Width-40,Control_AI &#41;;
	SetColor&#40;255,255,255,255&#41;;
	
	for&#40;int i=0;i<500;i++&#41;
	&#123;
		AddStar&#40; rand&#40;&#41;%gs_Global->Width,rand&#40;&#41;%gs_Global->Height,rand&#40;&#41;%255&#41;; 
	&#125;
	
	ball = new Ball&#40; gs_Global->Width/2,gs_Global->Height/2 &#41;;
	
	while&#40;1&#41;
	&#123;
		gsKit_clear&#40;gs_Global,MakeRgb&#40;0,0,0&#41;&#41;;
		
		UpdatePad&#40;&#41;;
		ReadPad&#40;&#41;;
		UpdateBats&#40;&#41;;
		StarsUpdateAndRender&#40;&#41;;
		RenderBats&#40;&#41;;
		UpdateAndRenderBall&#40;&#41;;
		
		if&#40; y <= 10  && &#40;x + width&#41; < &#40;gs_Global->Width - 10&#41;&#41;
			x+=1;
		else if&#40; &#40;y + height&#41;  <  &#40;VHeight - 10&#41; && &#40;x + width&#41; >= &#40;gs_Global->Width - 10&#41; &#41;
			y+=1;		
		else if&#40; &#40;y + height&#41; >=  &#40;VHeight - 10&#41; && x > 10 &#41;
			x-=1;
		else if&#40; y > 10 && x <= 10 &#41;
			y-=1;

	//	gsKit_prim_sprite&#40;gsGlobal, x, y, x + width, y + height, 4, MakeRgb&#40;255,0,0&#41;&#41;;
		
		//gsKit_prim_sprite&#40;gsGlobal,20,20,140,140,4,MakeRgba&#40;255,255,128,255&#41;&#41;;
		// RedTrans must be a oneshot for proper blending!
		//gsKit_prim_sprite&#40;gsGlobal, 100.0f, 100.0f, 200.0f, 200.0f, 5, MakeRgba&#40;128,128,128,128&#41;&#41;;



		gsKit_queue_exec&#40;gs_Global&#41;;

		// Flip before exec to take advantage of DMA execution double buffering.
		gsKit_sync_flip&#40;gs_Global&#41;;

	&#125;
	
	return 0;
&#125;
&#125;


Posted: Sun Jul 02, 2006 12:20 am
by jbit
Do not use the LIBSD from rom0: with ps2snd, the LIBSD from rom0 is EXTREMLY broken.
You can use libsd.irx from a ps2 game or use freesd.irx (from ps2sdk) instead!

Oh, and what link errors are you getting? I don't think you've pasted them anywhere.

Posted: Sun Jul 02, 2006 12:42 am
by Kojima
Yeah sorry, I thought I pasted it.

C:\ps2dev\gskit\examples\basic>make
ee-gcc -mno-crt0 -TC:/ps2dev/ps2sdk/ee/startup/linkfile -LC:/ps2dev/ps2sdk/ee/li
b \
-o basic.elf C:/ps2dev/ps2sdk/ee/startup/crt0.o basic.o -lpad -lgskit -l
dmakit -lstdc++ -lps2snd -lc -lc -lkernel
basic.o(.text+0xbb0): In function `main':
basic.cc: undefined reference to `SdSetParam(unsigned short, unsigned short)'
basic.o(.text+0xbbc):basic.cc: undefined reference to `SdSetParam(unsigned short
, unsigned short)'
basic.o(.text+0xbc8):basic.cc: undefined reference to `SdSetParam(unsigned short
, unsigned short)'
basic.o(.text+0xbd4):basic.cc: undefined reference to `SdSetParam(unsigned short
, unsigned short)'
collect2: ld returned 1 exit status
make: *** [basic.elf] Error 1

C:\ps2dev\gskit\examples\basic>


And thanks for the heads up, I'll go through my games see if theres a libsd.

Posted: Sun Jul 02, 2006 12:47 am
by jbit
Ah, it's probably because ps2snd's header doesn't have extern "C" things (I don't use C++ much on the PS2), so C++ is doing its function name mangling stuff, and ld can't find the functions.

I'll try fixing it now, update your SVN bin in a few minutes.

EDIT: Done, but not tested with A C++ program.
EDIT: Had to commit another revision, 1329, since i forgot to commit the main ps2snd.h file hte first time round.

Posted: Sun Jul 02, 2006 12:52 am
by Kojima
Nice one, thanks, I'll try it now and let you know if it works.

-edit-Yep works fine, thanks again.

Posted: Sun Jul 02, 2006 1:41 am
by Kojima
Hmm it compiles now, but as soon as it reaches the set volume call it freezes the ps2 completely. Not even ps2client reset unfreezes it, I need to manually reboot the ps2.

Any idea if it's another c++ related problem or a irx conflict?(I'm now using freesd found in the 03 june package from xorloser's site)

Posted: Sun Jul 02, 2006 2:13 am
by Kojima
Fixed it, didn't see the SdInit() call in the sound demo, worked soon as I added that.

Btw, can I legally include LibSD.irx from a commercial game or should I use freesd for stuff i release?

Posted: Sun Jul 02, 2006 3:09 am
by jbit
No, you can't legally include any Sony IRX in anything your release.
FreeSD is definatly usable enough for most things, if you enocunter any bugs please let me know. And I'd highly recommend developing and testing your code with only FreeSD.
(Unfortuantly FreeSD is based on quite an old LIBSD, but ps2snd was written against a relativly new version, so there may be some bugs)

In fact, I'm aware of one bug, which is FreeSD doesn't properly reset the SPU2, so sometimes the channels are in weird modes.

I now do this when initializing Sd... for both cores i do: (where "core" is 0 and 1)

Code: Select all

/* Stop all voices */
SdSetSwitch&#40;core | SD_SWITCH_KEYUP,   0xffffff&#41;;

/* Disable all pitch modulation */
SdSetSwitch&#40;core | SD_SWITCH_PMON, 0&#41;;

/* Switch off all noise generation */
SdSetSwitch&#40;core | SD_SWITCH_NON, 0&#41;;

/* Enable direct output */
SdSetSwitch&#40;core | SD_SWITCH_VMIXL, 0xffffff&#41;;
SdSetSwitch&#40;core | SD_SWITCH_VMIXR, 0xffffff&#41;;

/* Disable effects output */
SdSetSwitch&#40;core | SD_SWITCH_VMIXEL, 0&#41;;
SdSetSwitch&#40;core | SD_SWITCH_VMIXER, 0&#41;;

/* Set master volume of SPU core0 */
SdSetParam&#40;core | SD_PARAM_MVOLL, 0x3fff&#41;;
SdSetParam&#40;core | SD_PARAM_MVOLR, 0x3fff&#41;;
And then:

Code: Select all

/* Enable only direct voice output for core0 */
SdSetParam&#40;0 | SD_PARAM_MMIX, &#40;1<<10&#41; | &#40;1<<11&#41;&#41;;

/* NOTE&#58; core0s output goes to core1s external input, core1s output goes to the DAC. */
/* Enable direct voice output and external input for core1 */
SdSetParam&#40;1 | SD_PARAM_MMIX, &#40;1<<2&#41; | &#40;1<<3&#41; | &#40;1<<10&#41; | &#40;1<<11&#41;&#41;;
This seems to fix some fun noises I was getting without this code.

I want to move this init code into FreeSD, rather than requiring all apps that use sd to do it, but I'd like to do it correctly, so it's not done yet.

Posted: Sun Jul 02, 2006 3:22 am
by Kojima
Thanks, I'll use that if I get any of the same bugs (Which I probably, not like we're talking pcs/different configs)

Btw can you do single channel sounds with pssnd? I see theres only a single function called sndStreamPlay() which takes no 'channel' parameter or sound parameter.
or would I have to do it like on a gba and write my own mixer?

Posted: Sun Jul 02, 2006 3:27 am
by jbit
When streaming ADPCM with ps2snd you can use mono or stereo streams. But ps2snd only supports one stream at a time for now (in the future it'll probably support more).

Posted: Sun Jul 02, 2006 3:27 am
by Drakonite
You trigger a SD_SWITCH_KEYDOWN on a channel to start it playing.. there should be an example of that in whatever code jbit pointed you at

Posted: Sun Jul 02, 2006 3:35 am
by Kojima
Doesn't the core refer to each spu core, if so does that limit me to two channels which i have to mix myself? (I don't want streams I mean for normal in game soundfx)

Posted: Sun Jul 02, 2006 3:56 am
by Kojima
btw can you suggest a good prog to convert mp3/wavs etc to ADPCM? I can't find any that save at 48khz, and only the microsoft ADPCM format. (No idea if they're compatible.)

-edit- btw you need to do the extern "c" thing for ps2snd.h aswell. just did it and it works. (same deal as before without it)
I'd upload to the svn but i'm new to svn so i'm afraid i'll end up messing it up and destroying the community in one fell swoop :)

Posted: Sun Jul 02, 2006 4:49 am
by jbit
Kojima wrote:btw can you suggest a good prog to convert mp3/wavs etc to ADPCM?
You can use my ps2adpcm tool from ps2sdk, on a unix system with sox installed you can do:

Code: Select all

sox "input file" -t raw -r 48000 -c 1 -w -s - | ps2adpcm - "output file" 
To convert from anything sox supports (mp3/wav/aiff/ogg/etc) to ADPCM (replay "input file" with "output file")
That command will make a "one shot" (non-repeating) sample. Add "-l0" to the end if you want the sample to repeat from the start.


Kojima wrote:-edit- btw you need to do the extern "c" thing for ps2snd.h aswell. just did it and it works
I did that update a few seconds after the first update, recheck out, you should get it (but you might get a conflict if you edited it yourself).
Kojima wrote:Doesn't the core refer to each spu core, if so does that limit me to two channels which i have to mix myself? (I don't want streams I mean for normal in game soundfx)
As i've said before, each SPU core has 24 voices that you can use for playing samples, it has a couple of PCM streaming channels (which ps2snd doesn't really support decently yet).
ps2snd's streaming stuff fakes ADPCM streaming using one hardware voice per stream channel, and only support one stream at a time for now (so one or two channels), it could in theory support upto 24 stereo streams, mixed in hardware at any one time, but I don't know if the IOPs DMAC would be upto that, (and i don't really see a use for it).

For game sound FX, you do _NOT_ want to use the streaming functionality, only use the streaming stuff for music. The example I pasted before (from ps2kit) has examples of how to use ps2snd for sound FX (using different voices and KEYON registers, etc)

If you wait a few days, i should have a pretty decent tutorial up on my site, including some decent explanations on the concepts the SPU2 uses for audio output.

Posted: Sun Jul 02, 2006 4:53 am
by Kojima
Ok look forward to seeing it, please lay a post down with a link to your site when you do.

As for your tool, does it have a windows port? I dont use linux cos I could never get broadband to run on it.
-edit- found it with a file search, trying it now, thanks.

Posted: Sun Jul 02, 2006 4:56 am
by Drakonite
...you using cygwin? ... get it to install sox then, and jbit's tool is part of ps2sdk

Posted: Sun Jul 02, 2006 4:58 am
by Kojima
No afraid not, I'm using the prebuilt ps2 sdk. unless that includes some version of cyngwin or other. regular cygwin is too big for my hd(14gig with most of it used)

but like i said this build has his tool anyway.

Posted: Sun Jul 02, 2006 5:19 am
by Kojima
Hmm a couple of issues. I used this --
:\ps2dev\ps2sdk\bin>ps2adpcm c:\ps2dev\gskit\examples\basic\track1.wav ntrack1.
adpcm -s -c1024 -s1000
loop end!
-- to convert a mp3 into a 8bit stero pcm .wav in goldwave, it worked, but it was only 5mb compared to the wavs 40. then playing it, it was litterally 3-4x faster than it should be and distorted heavily.(Probably just the volume too high causing the distortion?)

But worse than that, ps2client reset no longer works. when i call it, the sound just loops a half a second interval(I.e (bleep)s up) and thats it. ps2client exits and ps2link doesn't reset.
Is this because I'm using v1.24 of ps2link? (been too lazy to use the new version)

Posted: Sun Jul 02, 2006 5:52 am
by Kojima
Just tried the new ps2link(v1.46) and it still crashes. nice init speed boost though ;p

-edit- just commented out the few lines of sound code and it now works perfectly, so definitely the sound lib interfering.
I'm using a mod-chip (Matrix Infinity) to boot, dunno whether that could be an issue or not.

Posted: Sun Jul 02, 2006 7:07 am
by jbit
The ps2adpcm tool doesn't understand wave, or aiff, or anything, it only takes in raw PCM, that's why i recommend using sox with it.
I'm not sure what's causing your lock-up, it sounds like it could be graphics related, rather than sound related. Although I assume you've read the README that comes with ps2snd which states you CAN'T use ps2client reset when streaming audio.... it's a known bug and is in the process of being fixed (hint: it's not ps2snds fault, it's to do with the network stack on the IOP).
EDIT: (But if you stop and close the stream, you can reset using ps2client safely though)

Please note that the SPU2 only has 2mbytes of sound ram, so you can only upload a maximum of about 1.8mbytes of samples. If you're streaming, this obviously doesn't matter and I've used streams upto about 100mbytes big without any problem.
And yes, the ADPCM output will be much smaller than the PCM input, iirc the ratio is about 3.5 or so.

Posted: Sun Jul 02, 2006 8:04 am
by Kojima
Oh ok I never saw the read me, I did think it might work if I stopped the stream but as soon as I realised the only way to do that would be to detect the rest, then stop the stream. which of course is (probably)impossible.

I'll just add a quick press l1+l2 hook to silently exit the game 'fore I reset.

As for wav, it is pcm. GoldWav lets you pick many wav formats, and I used pcm. it just uses the wav extension.(At least that's what it says.)
If that's wrong, can you reccomend a tool to save pcm data that's compatible?

Posted: Sun Jul 02, 2006 5:39 pm
by Drakonite
Kojima wrote: As for wav, it is pcm. GoldWav lets you pick many wav formats, and I used pcm. it just uses the wav extension.(At least that's what it says.)
If that's wrong, can you reccomend a tool to save pcm data that's compatible?
sox


...wav files are a container format, they just happen to typically be used for storing various formats of uncompressed pcm... there is still the header and such on it.

Posted: Sun Jul 02, 2006 6:12 pm
by Kojima
Just grabbed it, didn't know it had a windows release(That didn't require cygwin anyway)

Can you give me an example of converting a wav not using his tool(I'll use that after)? I tried jbits example and it started spewing out gibberish, my pc's internal speaker started bleeping and i had to reboot.

Posted: Sun Jul 02, 2006 6:16 pm
by Kojima
no matter, i just missed the output file parameter, probably why it outputed to the command line instead.

Posted: Sun Jul 02, 2006 6:28 pm
by Kojima
Ok now it sounds fine, no distortion but it's about 2x-3x faster than it should be. And it appears to be a conversation issue as the adpcm is only 5mb. (The raw file produced by sox and the wav are both 20mb)

Heres what i used to convert it.


C:\ps2dev\gskit\examples\basic>sox track1.wav -t raw -r 48000 -c 1 -w -s output.
raw

then

C:\ps2dev\gskit\examples\basic>ps2adpcm output.raw ntrack5.adpcm -s -c1024 -s100
0
loop end!

have i made a mistake somewhere?