Path: chuka.playstation.co.uk!scea!greg_labrec@interactive.sony.com From: "John Emmer" Newsgroups: scea.yaroze.programming.sound Subject: Re: Which function Plays Sound effects? Date: 7 Aug 1997 01:30:18 GMT Organization: Justice Center Lines: 353 Message-ID: <01bca2c8$b2ffd1c0$a7f135ce@jjustice.iquest.net> References: <33C360ED.3922@cobradev.demon.co.uk> <33C4A88F.6A7@interactive.sony.com> <33C9A08B.834@dfwmm.net> <33C9FA5E.6EDE@interactive.sony.com> Reply-To: "John Emmer" NNTP-Posting-Host: and-004-7.iquest.net X-Newsreader: Microsoft Internet News 4.70.1161 Developer Support wrote in article <33C9FA5E.6EDE@interactive.sony.com>... > OK, I've sorted out an example, it works with siocons, I'll put it in > the demos area aswell. Just cut and paste to use. Stuart, I hope you won't mind if I post this slightly modified version of your program which outputs to the PSX screen instead of to the computer, and also allows the user to change the note and pitch. I found your program very helpful in testing what the different parameters would do 'live' - so I didn't have to: modify my program, load 1/2 meg of data into the PSX, test program, modify program, load 1/2 meg of data, test, modify, load, test... It sucks that CodeWarrior won't exit clean with the system memory still intact - or this wouldn't be such a probelm to start with. /*************************************************************** * * * Copyright (C) 1997 by Sony Computer Entertainment * * All rights Reserved * * * * S. Ashley 14th Jul 97 * * * * Modified by John "Justice" Emmer to display to PSX screen * * rather than computer and allow changing note and pitch * * as well as prog and tone (8-6-97) * * * ***************************************************************/ #include // VAB and sequence location #define VH0_ADDR 0x80140000L #define VB0_ADDR 0x80160000L #define SEQ_ADDR 0x80100000L // pad stuff #define PADLup (1 <<12) #define PADLdown (1 <<14) #define PADLleft (1 <<15) #define PADLright (1 <<13) #define PADRup (1 << 4) #define PADRdown (1 << 6) #define PADRleft (1 << 7) #define PADRright (1 << 5) #define PADstart (1 <<11) #define PADselect (1 << 8) #define PADL1 (1 << 2) #define PADL2 (1 << 0) #define PADR1 (1 << 3) #define PADR2 (1 << 1) PACKET GpuPacketArea[2][ONE]; GsOT WorldOT [2]; GsOT_TAG OTTags [2][1<<1]; int activeBuff; short vab0; short seq1; char finish; char prog; char tone; char note = 60; char pitch = 0; // pad buffers volatile u_char *bb0, *bb1; void padControl(void); int programToneAvailable(u_short *VHAddr, u_short prog, u_short tone); main (void) { int i; finish = 0; // set up pad buffers GetPadBuf(&bb0, &bb1); SetVideoMode( MODE_NTSC ); // xres, yres, GPU non-interlace, no dither, 16bit GsInitGraph(320,240,4,0,0); GsDefDispBuff(0,0,0,240); //initialize ordering table for (i=0; i<2; i++) { WorldOT[i].length = 1; WorldOT[i].org = OTTags[i]; } // ResetGraph(0); // load system font into bottom right portion of frame buffer FntLoad(960,256); FntOpen(0,20,320,220,0,512); // transfer VAB data vab0 = SsVabTransfer((u_char *)VH0_ADDR, (u_char *)VB0_ADDR, -1, 1); if (vab0 < 0) { printf("VAB open failed\n"); exit(1); } // transfer sequence data seq1 = SsSeqOpen((u_long *)SEQ_ADDR, vab0); if (seq1 < 0) { printf("SEQ open failed\n"); } SsSetMVol(127, 127); SsSeqSetVol(seq1, 127, 127); SsSeqPlay(seq1, SSPLAY_PLAY, 0); printf("\nprog 0 tone 0"); do { FntPrint("**************************************\n"); FntPrint("* LEFT: play note RIGHT: stop notes *\n"); FntPrint("* TRIANGLE: prog + CROSS: prog - *\n"); FntPrint("* SQUARE: tone - CIRCLE: tone + *\n"); FntPrint("* L1: note - R1: note + *\n"); FntPrint("* L2: pitch - R2: pitch + *\n"); FntPrint("* UP: play the lot DOWN: stop play *\n"); FntPrint("* SELECT: pause START: continue *\n"); FntPrint("* START & SELECT : end *\n"); FntPrint("**************************************\n"); FntPrint("\n"); FntPrint("\nprog %d tone %d",prog,tone); FntPrint("\nnote %d pitch %d",note,pitch); padControl(); activeBuff = GsGetActiveBuff(); GsSetWorkBase((PACKET*)GpuPacketArea[activeBuff]); GsClearOt(0,0,&WorldOT[activeBuff]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&WorldOT[activeBuff]); GsDrawOt(&WorldOT[activeBuff]); FntFlush(-1); } while (!finish); SsSeqClose(seq1); // close sequence and VAB SsVabClose(vab0); } // *** controls *** void padControl(void) { static unsigned long opad; static short voice1; static short voice2; static char allPlay = 0; static int autoPlayPause = 0; u_long pad; // pad read pad = ~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24); // next tone (part of current program) if ((pad & PADRright) && !(opad & PADRright)) { do if (++tone > 15) tone = 0; while (!programToneAvailable((u_short *)VH0_ADDR,prog,tone)); } // previous tone (part of current program) if ((pad & PADRleft) && !(opad & PADRleft)) { do if (--tone > 15) tone = 15; while (!programToneAvailable((u_short *)VH0_ADDR,prog,tone)); } // set note if ((pad & PADR1) && !(opad & PADR1)) { if (++note < 0) note = 0; } if ((pad & PADL1) && !(opad & PADL1)) { if(--note < 0) note = 127; } // set pitch if ((pad & PADR2) && !(opad & PADR2)) { if (++pitch < 0) pitch = 0; } if ((pad & PADL2) && !(opad & PADL2)) { if(--pitch < 0) pitch = 127; } // next program if ((pad & PADRup) && !(opad & PADRup)) { tone = 0; do if (++prog < 0) prog = 0; while (!programToneAvailable((u_short *)VH0_ADDR,prog,tone)); // FntPrint("\nprog %d tone %d",prog,tone); } // previous program if ((pad & PADRdown) && !(opad & PADRdown)) { tone = 0; do if(--prog < 0) prog = 127; while (!programToneAvailable((u_short *)VH0_ADDR,prog,tone)); // FntPrint("\nprog %d tone %d",prog,tone); } // play each sound in turn from the beginning if ((pad & PADLup) && !(opad & PADLup)) { prog = 0; tone = 0; allPlay = 1; } // stop playing sounds in turn if ((pad & PADLdown) && !(opad & PADLdown)) { allPlay = 0; autoPlayPause = 0; } // bit that does the playing of all the sounds if (allPlay) { if (autoPlayPause == 0) { // FntPrint("\nprog %d tone %d", prog, tone); voice2 = SsUtKeyOn(vab0, prog, tone, note, pitch, 127, 127); autoPlayPause = VSync(-1); } if (VSync(-1) - autoPlayPause > 80) { SsUtKeyOff(voice2, vab0, prog, tone, 60); do if (++tone > 15) { tone = 0; if (++prog < 0) prog = 0; } while (!programToneAvailable((u_short *)VH0_ADDR, prog, tone)); autoPlayPause = 0; } } // play current sound (key hit) if ((pad & PADLleft) && !(opad & PADLleft)) voice1 = SsUtKeyOn(vab0, prog, tone, note, pitch, 127, 127); // and stop playing current sound (key release) if (!(pad & PADLleft) && (opad & PADLleft)) SsUtKeyOff(voice1, vab0, prog, tone, note); // stop playing all sounds if ((pad & PADLright) && !(opad & PADLright)) SsUtAllKeyOff(0); // pause sequence if ((pad & PADselect) && !(opad & PADselect)) SsSeqPause(seq1); // resume sequence if ((pad & PADstart) && !(opad & PADstart)) SsSeqReplay(seq1); // quit if ((pad & PADselect) && (pad & PADstart)) { SsSeqStop(seq1); finish = 1; } opad = pad; } // *** function to check the availability of a particular program and tone *** int programToneAvailable(u_short *VHAddr, u_short prog, u_short tone) { u_short numProg = *(VHAddr + 9); u_long t; u_long i = 0; // check tone is within limits and programs exist if (numProg == 0 || tone > 15) return 0; // check program is connected to tone do t = (u_long)VHAddr + 2080L + 512L * i + 20; while (i++ < numProg && *(u_short *)t != prog); if (*(u_short *)t != prog) return 0; // check tone connected to sound t = (u_long)VHAddr + 2080 + 512 * --i + 32 * tone + 22; if (*(u_short *)t > 0) return 1; else return 0; } -- John Emmer Video Game Enthusiast, Philosopher, Fledgling Programmer jjustice@cs.bsu.edu jjustice@iquest.net jpemmer@bsuvc.bsu.edu Vectrex; 7800, Supercharger, Lynx, Jaguar; NES, SNES, Virtual Boy; Turbo Duo & Express; SG, SGCD, 32X, Saturn; 3DO; PlayStation, Yaroze; C64, A600, A1200, P100; Arcade Centipede, Spy Hunter, Neo-Geo; BA, MA, ABD