| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830 |
- #include <iostream>
- #include <fstream>
- #include <iomanip>
- #include "SoundManager.h"
- #include "SoundBackend.h"
- #include "backends/SoundBackendSDL.h"
- #ifdef _MSC_VER
- #include <windows.h>
- #else
- #include <sys/time.h>
- #endif
- SoundManager *SOUNDMAN = NULL;
- SoundBackend *SBE = NULL;
- #ifndef HIWORD
- #define HIWORD(l) ((WORD) (((DWORD) (l) >> 16) & 0xFFFF))
- #endif
- #ifndef LOWORD
- #define LOWORD(a) ((WORD)(a))
- #endif
- typedef unsigned short int WORD;
- #ifndef _MSC_VER
- typedef unsigned int DWORD;
- #endif
- unsigned long RateTable[160];
- // REVERB info and timing vars...
- int *sRVBPlay = NULL;
- int *sRVBEnd = NULL;
- int *sRVBStart = NULL;
- // some delay factor for reverb
- int iReverbOff = -1;
- int iReverbRepeat = 0;
- int iReverbNum = 1;
- xa_decode_t * xapGlobal=0;
- u32 * XAFeed = NULL;
- u32 * XAPlay = NULL;
- u32 * XAStart = NULL;
- u32 * XAEnd = NULL;
- u32 XARepeat = 0;
- u32 XALastVal = 0;
- int iLeftXAVol = 32767;
- int iRightXAVol = 32767;
- static int gauss_ptr = 0;
- static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- #define gvall0 gauss_window[gauss_ptr]
- #define gvall(x) gauss_window[(gauss_ptr+x)&3]
- #define gvalr0 gauss_window[4+gauss_ptr]
- #define gvalr(x) gauss_window[4+((gauss_ptr+x)&3)]
- void SetupTimer();
- void RemoveTimer();
- const unsigned char version = 1;
- const unsigned char revision = 0;
- const unsigned char build = 0;
- // psx buffer / addresses
- unsigned short regArea[10000];
- unsigned short spuMem[256 * 1024];
- unsigned char * spuMemC;
- unsigned char * pSpuIrq = 0;
- unsigned char * pSpuBuffer;
- // user settings
- int iUseXA = 1;
- int iVolume = 3;
- int iXAPitch = 1;
- int iUseTimer = 2;
- int iSPUIRQWait = 1;
- int iDebugMode = 0;
- int iRecordMode = 0;
- int iUseReverb = 2;
- int iUseInterpolation = 2;
- //int iDisStereo = 0;
- // MAIN infos struct for each channel
- // channel + 1 infos (1 is security for fmod handling)
- SPUCHAN s_chan[MAXCHAN + 1];
- REVERBInfo rvb;
- // global noise generator
- unsigned long dwNoiseVal = 1;
- int iWatchDog = 0;
- // some vars to store psx reg infos
- unsigned short spuCtrl = 0;
- unsigned short spuStat = 0;
- unsigned short spuIrq = 0;
- // address into spu mem
- unsigned long spuAddr = 0xffffffff;
- // thread handlers
- int bEndThread = 0;
- int bThreadEnded = 0;
- int bSpuInit = 0;
- int bSPUIsOpen = 0;
- // flags for faster testing, if new channel starts
- unsigned long dwNewChannel = 0;
- // func of main emu, called on spu irq
- void (*irqCallback)(void) = 0;
- void (*cddavCallback)(unsigned short, unsigned short) = 0;
- // certain globals (were local before, but
- // with the new timeproc I need em global)
- static const int f[5][2] =
- {
- { 0, 0},
- { 60, 0},
- {115, -52},
- { 98, -55},
- {122, -60}
- };
- int SSumR[NSSIZE];
- int SSumL[NSSIZE];
- int iCycle = 0;
- short * pS;
- // last channel processed on spu irq in timer mode
- static int lastch = -1;
- // last ns pos
- static int lastns = 0;
- // secure start counter
- static int iSecureStart = 0;
- SoundManager::SoundManager()
- {
- u8 *buffer;
- /* SPU initialization */
- SPUinit();
- SPUopen();
- /* base initialization of main registers */
- u16 temp;
- SPUwriteRegister(0x1f801d80, 0x0000);
- SPUwriteRegister(0x1f801d82, 0x0000);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0x0000);
- SPUwriteRegister(0x1f801d80, 0x0000);
- SPUwriteRegister(0x1f801d82, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801dae);
- SPUwriteRegister(0x1f801dac, 0x0004);
- // H_SPUvolL
- SPUwriteRegister(0x1f801d84, 0x0000);
- // H_SPUvolR
- SPUwriteRegister(0x1f801d86, 0x0000);
- // H_SPUoff1
- SPUwriteRegister(0x1f801d8c, 0xffff);
- // H_SPUoff2
- SPUwriteRegister(0x1f801d8e, 0xffff);
- // H_RVBon1
- SPUwriteRegister(0x1f801d98, 0x0000);
- // H_RVBon2
- SPUwriteRegister(0x1f801d9a, 0x0000);
- // H_Fmod1
- SPUwriteRegister(0x1f801d90, 0x0000);
- // H_Fmod2
- SPUwriteRegister(0x1f801d92, 0x0000);
- // H_Noise1
- SPUwriteRegister(0x1f801d94, 0x0000);
- // H_Noise2
- SPUwriteRegister(0x1f801d96, 0x0000);
- // H_CDLeft
- SPUwriteRegister(0x1f801db0, 0x0000);
- // H_CDRight
- SPUwriteRegister(0x1f801db2, 0x0000);
- SPUwriteRegister(0x1f801db4, 0x0000);
- SPUwriteRegister(0x1f801db6, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801dae);
- // H_SPUaddr
- SPUwriteRegister(0x1f801da6, 0x0200);
- // H_SPUdata, hmmm... why 8 times??
- for(int i = 0; i < 8; ++i)
- SPUwriteRegister(0x1f801da8, 0x0707);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0x0010);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801dae);
- // returns 0x0010
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801dae);
- /* clear channels */
- for(int i = 0; i < 24; ++i)
- {
- // left volume
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x00, 0x0000);
- // right volume
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x02, 0x0000);
- // pitch
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x04, 0x3fff);
- // start address
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x06, 0x0200);
- // level with pre-calcs
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x08, 0x0000);
- // adsr times with precalcs
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x0a, 0x0000);
- }
- /* on/off SPU channels, why?? ;) */
- // H_SPUon1
- SPUwriteRegister(0x1f801d88, 0xffff);
- // H_SPUon2
- SPUwriteRegister(0x1f801d8a, 0x00ff);
- // H_SPUoff1
- SPUwriteRegister(0x1f801d8c, 0xffff);
- // H_SPUoff2
- SPUwriteRegister(0x1f801d8e, 0x00ff);
- /* reverb initialization */
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc000);
- // H_SPUReverbAddr
- SPUwriteRegister(0x1f801da2, 0xfffe);
- /* another dma transfer [unknown yet] */
- // temporary writing another dma dump gotten with real emu
- {
- std::ifstream iF;
- iF.open("data/dmadump2.bin", std::ios_base::binary);
- u32 datasize = 64;
- buffer = new u8[datasize];
- iF.read((char *)buffer, datasize);
- iF.close();
- if(!this->PsxWriteDMA(0xedfc, buffer, datasize))
- {
- std::cout << "[SoundManager] error: failed to DMA write unknown data" << std::endl;
- exit(EXIT_FAILURE);
- }
- delete [] buffer;
- }
- /* CDaudio controls? */
- SPUwriteRegister(0x1f801d80, 0x3fff);
- SPUwriteRegister(0x1f801d82, 0x3fff);
- // H_CDLeft
- SPUwriteRegister(0x1f801db0, 0x7fff);
- // H_CDRight
- SPUwriteRegister(0x1f801db2, 0x7fff);
- SPUwriteRegister(0x1f801db4, 0x0000);
- SPUwriteRegister(0x1f801db6, 0x0000);
- /* here turning something important on, or clear something, me thinks... */
- // returns 0xc0000
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc000);
- // returns 0xc000
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc001);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc001);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc001);
- /* clear channels volume again, for safe?? (cleared before) */
- for(int i = 0; i < 24; ++i)
- {
- // left volume
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x00, 0x0000);
- // right volume
- SPUwriteRegister(m_REGISTER_BASE + 16 * i + 0x02, 0x0000);
- }
- /* another init ;) */
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc001);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUoff1
- SPUwriteRegister(0x1f801d8c, 0x0000);
- // H_SPUoff2
- SPUwriteRegister(0x1f801d8e, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // H_RVBon1
- SPUwriteRegister(0x1f801d98, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // H_RVBon2
- SPUwriteRegister(0x1f801d9a, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // H_RVBon1
- SPUwriteRegister(0x1f801d98, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // H_RVBon2
- SPUwriteRegister(0x1f801d9a, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // H_FMod1
- SPUwriteRegister(0x1f801d90, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // H_FMod2
- SPUwriteRegister(0x1f801d92, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // H_FMod1
- SPUwriteRegister(0x1f801d90, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // H_FMod2
- SPUwriteRegister(0x1f801d92, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // H_Noise1
- SPUwriteRegister(0x1f801d94, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // H_Noise2
- SPUwriteRegister(0x1f801d96, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // H_Noise1
- SPUwriteRegister(0x1f801d94, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // H_Noise2
- SPUwriteRegister(0x1f801d96, 0x0000);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc001);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUrvolL
- SPUwriteRegister(0x1f801d84, 0x0000);
- // H_SPUrvolR
- SPUwriteRegister(0x1f801d86, 0x0000);
- /* set reverb parameters?? */
- // H_Reverb
- SPUwriteRegister(0x1f801dc0, 0x00e3);
- SPUwriteRegister(0x1f801dc2, 0x00a9);
- SPUwriteRegister(0x1f801dc4, 0x6f60);
- SPUwriteRegister(0x1f801dc6, 0x4fa8);
- SPUwriteRegister(0x1f801dc8, 0xbce0);
- SPUwriteRegister(0x1f801dca, 0x4510);
- SPUwriteRegister(0x1f801dcc, 0xbef0);
- SPUwriteRegister(0x1f801dce, 0xa680);
- SPUwriteRegister(0x1f801dd0, 0x5680);
- SPUwriteRegister(0x1f801dd2, 0x52c0);
- SPUwriteRegister(0x1f801dd4, 0x0dfb);
- SPUwriteRegister(0x1f801dd6, 0x0b58);
- SPUwriteRegister(0x1f801dd8, 0x0d09);
- SPUwriteRegister(0x1f801dda, 0x0a3c);
- SPUwriteRegister(0x1f801ddc, 0x0bd9);
- SPUwriteRegister(0x1f801dde, 0x0973);
- SPUwriteRegister(0x1f801de0, 0x0b59);
- SPUwriteRegister(0x1f801de2, 0x08da);
- SPUwriteRegister(0x1f801de4, 0x08d9);
- SPUwriteRegister(0x1f801de6, 0x05e9);
- SPUwriteRegister(0x1f801de8, 0x07ec);
- SPUwriteRegister(0x1f801dea, 0x04b0);
- SPUwriteRegister(0x1f801dec, 0x06ef);
- SPUwriteRegister(0x1f801dee, 0x03d2);
- SPUwriteRegister(0x1f801df0, 0x05ea);
- SPUwriteRegister(0x1f801df2, 0x031d);
- SPUwriteRegister(0x1f801df4, 0x031c);
- SPUwriteRegister(0x1f801df6, 0x0238);
- SPUwriteRegister(0x1f801df8, 0x0154);
- SPUwriteRegister(0x1f801dfa, 0x00aa);
- SPUwriteRegister(0x1f801dfc, 0x8000);
- SPUwriteRegister(0x1f801dfe, 0x8000);
- /* and finishing dma transfer of zeroes :), phew */
- {
- u32 datasize = 1024;
- u8 *buffer = new u8[datasize];
- memset((void *)buffer, 0x00, datasize);
- for(int i = 0; i < 28; ++i)
- {
- if(!this->PsxWriteDMA(0xf204 + 128 * i, buffer, datasize))
- {
- std::cout << "[SoundManager] error: failed to DMA write 0x00 data" << std::endl;
- exit(EXIT_FAILURE);
- }
- }
- delete [] buffer;
- }
- /* last init */
- // H_SPUReverbAddr
- SPUwriteRegister(0x1f801da2, 0xf204);
- // returns 0xc001
- temp = SPUreadRegister(0x1f801daa);
- // H_SPUctrl
- SPUwriteRegister(0x1f801daa, 0xc081);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // H_Noise1
- SPUwriteRegister(0x1f801d94, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // H_Noise2
- SPUwriteRegister(0x1f801d96, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d94);
- // H_Noise1
- SPUwriteRegister(0x1f801d94, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d96);
- // H_Noise2
- SPUwriteRegister(0x1f801d96, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // H_RVBon1
- SPUwriteRegister(0x1f801d98, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // H_RVBon2
- SPUwriteRegister(0x1f801d9a, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d98);
- // H_RVBon1
- SPUwriteRegister(0x1f801d98, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d9a);
- // H_RVBon2
- SPUwriteRegister(0x1f801d9a, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // H_FMod1
- SPUwriteRegister(0x1f801d90, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // H_FMod2
- SPUwriteRegister(0x1f801d92, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d90);
- // H_FMod1
- SPUwriteRegister(0x1f801d90, 0x0000);
- // returns 0x0000
- temp = SPUreadRegister(0x1f801d92);
- // H_FMod2
- SPUwriteRegister(0x1f801d92, 0x0000);
- // H_SPUoff1
- SPUwriteRegister(0x1f801d8c, 0xffff);
- // H_SPUoff2
- SPUwriteRegister(0x1f801d8e, 0x00ff);
- }
- bool SoundManager::PsxWriteDMA(u16 arg_address, u8 *arg_data, u32 arg_length)
- {
- u16 temp;
- // write and verify destination address
- SPUwriteRegister(0x1f801da6, arg_address);
- if(SPUreadRegister(0x1f801da6) != arg_address)
- return false;
- // set and verify dma operation
- temp = SPUreadRegister(0x1f801daa);
- temp |= 32;
- SPUwriteRegister(0x1f801daa, temp);
- if(SPUreadRegister(0x1f801daa) != temp)
- return false;
- SPUwriteDMAMem((unsigned short *)arg_data, arg_length / 2);
- // clear and verify dma operation
- temp = SPUreadRegister(0x1f801daa);
- temp &= ~32;
- SPUwriteRegister(0x1f801daa, temp);
- if(SPUreadRegister(0x1f801daa) != temp)
- return false;
- return true;
- }
- SoundManager::~SoundManager()
- {
- // close SPU
- SPUclose();
- }
- void SoundManager::Update()
- {
- SPUasync(0xc000);
- }
- void
- SoundManager::PsxChannelPlay( u8 arg_channel )
- {
- if( arg_channel < 16 )
- {
- // H_SPUon1
- SPUwriteRegister( 0x1f801d88, 1 << arg_channel );
- }
- else if( arg_channel >= 16 && arg_channel < 24 )
- {
- // H_SPUon2
- SPUwriteRegister( 0x1f801d8a, 1 << ( arg_channel - 16 ) );
- }
- }
- void
- SoundManager::PsxChannelStop( u8 arg_channel )
- {
- if( arg_channel < 16 )
- {
- // H_SPUoff1
- SPUwriteRegister( 0x1f801d8c, 1 << arg_channel );
- }
- else if( arg_channel >= 16 && arg_channel < 24 )
- {
- // H_SPUoff2
- SPUwriteRegister( 0x1f801d8e, 1 << ( arg_channel - 16 ) );
- }
- }
- void
- SoundManager::PsxReverbOn( u8 arg_channel )
- {
- if( arg_channel < 16 )
- {
- // H_RVBon1
- SPUwriteRegister( 0x1f801d98, 1 << arg_channel );
- }
- else if( arg_channel >= 16 && arg_channel < 24 )
- {
- // H_RVBon2
- SPUwriteRegister( 0x1f801d9a, 1 << ( arg_channel - 16 ) );
- }
- }
- void
- SoundManager::PsxSetReverbDepth( u16 arg_left, u16 arg_right )
- {
- SPUwriteRegister( 0x1f801d84, arg_left );
- SPUwriteRegister( 0x1f801d86, arg_right );
- }
- void
- SoundManager::SetVoiceStartAddress( u8 arg_voice, u32 arg_address )
- {
- if( arg_voice < 0x18 )
- {
- // if address isn't divisible by 8, it's
- // increased to the next value divisible by 8
- if( arg_address % 8 )
- {
- arg_address += 8;
- arg_address &= ~7;
- }
- SPUwriteRegister( m_PSX_SPU_BASE + arg_voice * 0x10 + 0x06, ( u16 )( arg_address / 8 ) );
- }
- }
- void SoundManager::SetVoiceLoopAddress(u8 arg_voice, u32 arg_address)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- // if address isn't divisible by 8, it's
- // increased to the next value divisible by 8
- if(arg_address % 8)
- {
- arg_address += 8;
- arg_address &= ~7;
- }
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x0e, (u16)(arg_address / 8));
- }
- // +++
- void SoundManager::SetVoiceVolume(u8 arg_voice,
- s16 arg_volume_left, s16 arg_volume_right)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x00,
- arg_volume_left & 0x7fff);
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x02,
- arg_volume_right & 0x7fff);
- }
- // +++
- void SoundManager::SetVoicePitch(u8 arg_voice, u16 arg_pitch)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_pitch >= 0x4000)
- {
- std::cout << "*** error: wrong pitch!" << std::endl;
- return;
- }
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x04, arg_pitch);
- }
- // +++
- void SoundManager::SetVoiceAttackRate(u8 arg_voice,
- u16 arg_rate, SpuRateMode arg_mode)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_rate >= 0x80)
- {
- std::cout << "*** error: wrong attack rate!" << std::endl;
- return;
- }
- u16 value = (arg_mode == SPU_VOICE_EXPIncN) ? (1 << 7) : 0;
- value |= arg_rate;
- value <<= 8;
- u16 temp = SPUreadRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08) & 0xFF;
- temp |= value;
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08, temp);
- }
- // +++
- void SoundManager::SetVoiceSustainRate(u8 arg_voice,
- u16 arg_rate, SpuRateMode arg_mode)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_rate >= 0x80)
- {
- std::cout << "*** error: wrong sustain rate!" << std::endl;
- return;
- }
- u16 value;
- switch(arg_mode)
- {
- case SPU_VOICE_EXPIncN:
- value = 0x200;
- break;
- case SPU_VOICE_LINEARDecN:
- value = 0x100;
- break;
- case SPU_VOICE_EXPDec:
- value = 0x300;
- break;
- default:
- std::cout << "*** error: wrong sustain rate mode!" << std::endl;
- case SPU_VOICE_LINEARIncN:
- value = 0x000;
- break;
- }
- u16 temp = SPUreadRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x0a) & 0x3F;
- temp |= (arg_rate | value) << 6;
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x0a, temp);
- }
- // +++
- void SoundManager::SetVoiceReleaseRate(u8 arg_voice,
- u16 arg_rate, SpuRateMode arg_mode)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_rate >= 0x20)
- {
- std::cout << "*** error: wrong release rate!" << std::endl;
- return;
- }
- u16 value = (arg_mode == SPU_VOICE_EXPDec) ? (1 << 5) : 0;
- value |= arg_rate;
- u16 temp = SPUreadRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x0a)
- & 0xFFC0;
- temp |= value;
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x0a, temp);
- }
- // +++
- void SoundManager::SetVoiceDecayRate(u8 arg_voice, u16 arg_rate)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_rate >= 0x10)
- {
- std::cout << "*** error: wrong decay rate!" << std::endl;
- return;
- }
- u16 temp = SPUreadRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08)
- & 0xFF0F;
- temp |= arg_rate << 4;
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08, temp);
- }
- // +++
- void SoundManager::SetVoiceSustainLevel(u8 arg_voice, u16 arg_level)
- {
- if(arg_voice >= 0x18)
- {
- std::cout << "*** error: wrong channel!" << std::endl;
- return;
- }
- if(arg_level >= 0x10)
- {
- std::cout << "*** error: wrong sustain level!" << std::endl;
- return;
- }
- u16 temp = SPUreadRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08)
- & 0xFFF0;
- temp |= arg_level;
- SPUwriteRegister(m_PSX_SPU_BASE + arg_voice * 0x10 + 0x08, temp);
- }
- void InitADSR()
- {
- unsigned long r = 3;
- unsigned long rs = 1;
- unsigned long rd = 0;
- int i;
- // build the rate table according to Neill's rules
- memset(RateTable, 0, sizeof(unsigned long) * 160);
- // we start at pos 32 with the real values... everything before is 0
- for(i = 32; i < 160; i++)
- {
- if(r < 0x3FFFFFFF)
- {
- r += rs;
- rd++;
- if(rd == 5)
- {
- rd = 1;
- rs *= 2;
- }
- }
- if(r > 0x3FFFFFFF)
- r = 0x3FFFFFFF;
- RateTable[i] = r;
- }
- }
- void StartADSR(int ch)
- {
- s_chan[ch].ADSRX.lVolume = 1;
- s_chan[ch].ADSRX.State = 0;
- s_chan[ch].ADSRX.EnvelopeVol = 0;
- }
- int MixADSR(int ch)
- {
- // channel stopped
- if(s_chan[ch].bStop)
- {
- // release
- if(s_chan[ch].ADSRX.ReleaseModeExp)
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol >> 28) & 0x07)
- {
- case 0:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 0 + 32];
- break;
- case 1:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 4 + 32];
- break;
- case 2:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 6 + 32];
- break;
- case 3:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 8 + 32];
- break;
- case 4:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 9 + 32];
- break;
- case 5:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 10 + 32];
- break;
- case 6:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 11 + 32];
- break;
- case 7:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x18 + 12 + 32];
- break;
- }
- }
- else
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.ReleaseRate^0x1F)) - 0x0C + 32];
- if(s_chan[ch].ADSRX.EnvelopeVol < 0)
- {
- s_chan[ch].ADSRX.EnvelopeVol = 0;
- s_chan[ch].bOn = 0;
- }
- s_chan[ch].ADSRX.lVolume = s_chan[ch].ADSRX.EnvelopeVol >> 21;
- return s_chan[ch].ADSRX.lVolume;
- }
- // channel not stopped
- else
- {
- // attack
- if(s_chan[ch].ADSRX.State == 0)
- {
- if(s_chan[ch].ADSRX.AttackModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol < 0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.AttackRate^0x7F) - 0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.AttackRate^0x7F) - 0x18 + 32];
- }
- else
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.AttackRate^0x7F) - 0x10 + 32];
- if(s_chan[ch].ADSRX.EnvelopeVol < 0)
- {
- s_chan[ch].ADSRX.EnvelopeVol = 0x7FFFFFFF;
- s_chan[ch].ADSRX.State = 1;
- }
- s_chan[ch].ADSRX.lVolume = s_chan[ch].ADSRX.EnvelopeVol >> 21;
- return s_chan[ch].ADSRX.lVolume;
- }
- // decay
- if(s_chan[ch].ADSRX.State == 1)
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol >> 28) & 0x07)
- {
- case 0:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 0 + 32];
- break;
- case 1:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 4 + 32];
- break;
- case 2:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 6 + 32];
- break;
- case 3:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 8 + 32];
- break;
- case 4:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 9 + 32];
- break;
- case 5:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 10 + 32];
- break;
- case 6:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 11 + 32];
- break;
- case 7:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[(4 *
- (s_chan[ch].ADSRX.DecayRate^0x1F)) - 0x18 + 12 + 32];
- break;
- }
- if(s_chan[ch].ADSRX.EnvelopeVol < 0)
- s_chan[ch].ADSRX.EnvelopeVol = 0;
- if(((s_chan[ch].ADSRX.EnvelopeVol >> 27) & 0xF) <=
- s_chan[ch].ADSRX.SustainLevel)
- s_chan[ch].ADSRX.State = 2;
- s_chan[ch].ADSRX.lVolume = s_chan[ch].ADSRX.EnvelopeVol >> 21;
- return s_chan[ch].ADSRX.lVolume;
- }
- // sustain
- if(s_chan[ch].ADSRX.State == 2)
- {
- if(s_chan[ch].ADSRX.SustainIncrease)
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- {
- if(s_chan[ch].ADSRX.EnvelopeVol < 0x60000000)
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.SustainRate^0x7F) - 0x10 + 32];
- else
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.SustainRate^0x7F) - 0x18 + 32];
- }
- else
- s_chan[ch].ADSRX.EnvelopeVol += RateTable[
- (s_chan[ch].ADSRX.SustainRate^0x7F) - 0x10 + 32];
- if(s_chan[ch].ADSRX.EnvelopeVol < 0)
- s_chan[ch].ADSRX.EnvelopeVol = 0x7FFFFFFF;
- }
- else
- {
- if(s_chan[ch].ADSRX.SustainModeExp)
- {
- switch((s_chan[ch].ADSRX.EnvelopeVol >> 28) & 0x7)
- {
- case 0:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 0 + 32];
- break;
- case 1:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 4 + 32];
- break;
- case 2:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 6 + 32];
- break;
- case 3:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 8 + 32];
- break;
- case 4:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 9 + 32];
- break;
- case 5:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 10 + 32];
- break;
- case 6:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 11 + 32];
- break;
- case 7:
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F))
- - 0x1B + 12 + 32];
- break;
- }
- }
- else
- s_chan[ch].ADSRX.EnvelopeVol -= RateTable[
- ((s_chan[ch].ADSRX.SustainRate^0x7F)) - 0x0F + 32];
- if(s_chan[ch].ADSRX.EnvelopeVol < 0)
- s_chan[ch].ADSRX.EnvelopeVol = 0;
- }
- s_chan[ch].ADSRX.lVolume = s_chan[ch].ADSRX.EnvelopeVol >> 21;
- return s_chan[ch].ADSRX.lVolume;
- }
- }
- return 0;
- }
- unsigned short SPUreadDMA()
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "SPUreadDMA()" << std::endl;
- #endif
- unsigned short s = spuMem[spuAddr >> 1];
- spuAddr += 2;
- if(spuAddr > 0x7ffff)
- spuAddr = 0;
- iWatchDog = 0;
- return s;
- }
- void SPUreadDMAMem(unsigned short *pusPSXMem, int iSize)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "SPUreadDMAMem()" << std::endl;
- #endif
- int i;
- for(i = 0; i < iSize; i++)
- {
- // spu addr got by writeregister
- *pusPSXMem++ = spuMem[spuAddr >> 1];
- // inc spu addr
- spuAddr += 2;
- // wrap
- if(spuAddr > 0x7ffff)
- spuAddr = 0;
- }
- iWatchDog = 0;
- }
- // to investigate: do sound data updates by writedma affect spu
- // irqs? Will an irq be triggered, if new data is written to
- // the memory irq address?
- void SPUwriteDMA(unsigned short val)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "SPUwriteDMA()" << std::endl;
- #endif
- // spu addr got by writeregister
- spuMem[spuAddr >> 1] = val;
- // inc spu addr
- spuAddr += 2;
- // wrap
- if(spuAddr > 0x7ffff)
- spuAddr = 0;
- iWatchDog = 0;
- }
- void SPUwriteDMAMem(unsigned short *pusPSXMem, int iSize)
- {
- int i;
- for ( i = 0; i < iSize; i++ )
- {
- // spu addr got by writeregister
- spuMem[spuAddr >> 1] = *pusPSXMem++;
- // inc spu addr
- spuAddr += 2;
- // wrap
- if(spuAddr > 0x7ffff)
- {
- spuAddr = 0;
- }
- }
- iWatchDog = 0;
- }
- const int gauss[] =
- {
- 0x172, 0x519, 0x176, 0x000, 0x16E, 0x519, 0x17A, 0x000,
- 0x16A, 0x518, 0x17D, 0x000, 0x166, 0x518, 0x181, 0x000,
- 0x162, 0x518, 0x185, 0x000, 0x15F, 0x518, 0x189, 0x000,
- 0x15B, 0x518, 0x18D, 0x000, 0x157, 0x517, 0x191, 0x000,
- 0x153, 0x517, 0x195, 0x000, 0x150, 0x517, 0x19A, 0x000,
- 0x14C, 0x516, 0x19E, 0x000, 0x148, 0x516, 0x1A2, 0x000,
- 0x145, 0x515, 0x1A6, 0x000, 0x141, 0x514, 0x1AA, 0x000,
- 0x13E, 0x514, 0x1AE, 0x000, 0x13A, 0x513, 0x1B2, 0x000,
- 0x137, 0x512, 0x1B7, 0x001, 0x133, 0x511, 0x1BB, 0x001,
- 0x130, 0x511, 0x1BF, 0x001, 0x12C, 0x510, 0x1C3, 0x001,
- 0x129, 0x50F, 0x1C8, 0x001, 0x125, 0x50E, 0x1CC, 0x001,
- 0x122, 0x50D, 0x1D0, 0x001, 0x11E, 0x50C, 0x1D5, 0x001,
- 0x11B, 0x50B, 0x1D9, 0x001, 0x118, 0x50A, 0x1DD, 0x001,
- 0x114, 0x508, 0x1E2, 0x001, 0x111, 0x507, 0x1E6, 0x002,
- 0x10E, 0x506, 0x1EB, 0x002, 0x10B, 0x504, 0x1EF, 0x002,
- 0x107, 0x503, 0x1F3, 0x002, 0x104, 0x502, 0x1F8, 0x002,
- 0x101, 0x500, 0x1FC, 0x002, 0x0FE, 0x4FF, 0x201, 0x002,
- 0x0FB, 0x4FD, 0x205, 0x003, 0x0F8, 0x4FB, 0x20A, 0x003,
- 0x0F5, 0x4FA, 0x20F, 0x003, 0x0F2, 0x4F8, 0x213, 0x003,
- 0x0EF, 0x4F6, 0x218, 0x003, 0x0EC, 0x4F5, 0x21C, 0x004,
- 0x0E9, 0x4F3, 0x221, 0x004, 0x0E6, 0x4F1, 0x226, 0x004,
- 0x0E3, 0x4EF, 0x22A, 0x004, 0x0E0, 0x4ED, 0x22F, 0x004,
- 0x0DD, 0x4EB, 0x233, 0x005, 0x0DA, 0x4E9, 0x238, 0x005,
- 0x0D7, 0x4E7, 0x23D, 0x005, 0x0D4, 0x4E5, 0x241, 0x005,
- 0x0D2, 0x4E3, 0x246, 0x006, 0x0CF, 0x4E0, 0x24B, 0x006,
- 0x0CC, 0x4DE, 0x250, 0x006, 0x0C9, 0x4DC, 0x254, 0x006,
- 0x0C7, 0x4D9, 0x259, 0x007, 0x0C4, 0x4D7, 0x25E, 0x007,
- 0x0C1, 0x4D5, 0x263, 0x007, 0x0BF, 0x4D2, 0x267, 0x008,
- 0x0BC, 0x4D0, 0x26C, 0x008, 0x0BA, 0x4CD, 0x271, 0x008,
- 0x0B7, 0x4CB, 0x276, 0x009, 0x0B4, 0x4C8, 0x27B, 0x009,
- 0x0B2, 0x4C5, 0x280, 0x009, 0x0AF, 0x4C3, 0x284, 0x00A,
- 0x0AD, 0x4C0, 0x289, 0x00A, 0x0AB, 0x4BD, 0x28E, 0x00A,
- 0x0A8, 0x4BA, 0x293, 0x00B, 0x0A6, 0x4B7, 0x298, 0x00B,
- 0x0A3, 0x4B5, 0x29D, 0x00B, 0x0A1, 0x4B2, 0x2A2, 0x00C,
- 0x09F, 0x4AF, 0x2A6, 0x00C, 0x09C, 0x4AC, 0x2AB, 0x00D,
- 0x09A, 0x4A9, 0x2B0, 0x00D, 0x098, 0x4A6, 0x2B5, 0x00E,
- 0x096, 0x4A2, 0x2BA, 0x00E, 0x093, 0x49F, 0x2BF, 0x00F,
- 0x091, 0x49C, 0x2C4, 0x00F, 0x08F, 0x499, 0x2C9, 0x00F,
- 0x08D, 0x496, 0x2CE, 0x010, 0x08B, 0x492, 0x2D3, 0x010,
- 0x089, 0x48F, 0x2D8, 0x011, 0x086, 0x48C, 0x2DC, 0x011,
- 0x084, 0x488, 0x2E1, 0x012, 0x082, 0x485, 0x2E6, 0x013,
- 0x080, 0x481, 0x2EB, 0x013, 0x07E, 0x47E, 0x2F0, 0x014,
- 0x07C, 0x47A, 0x2F5, 0x014, 0x07A, 0x477, 0x2FA, 0x015,
- 0x078, 0x473, 0x2FF, 0x015, 0x076, 0x470, 0x304, 0x016,
- 0x075, 0x46C, 0x309, 0x017, 0x073, 0x468, 0x30E, 0x017,
- 0x071, 0x465, 0x313, 0x018, 0x06F, 0x461, 0x318, 0x018,
- 0x06D, 0x45D, 0x31D, 0x019, 0x06B, 0x459, 0x322, 0x01A,
- 0x06A, 0x455, 0x326, 0x01B, 0x068, 0x452, 0x32B, 0x01B,
- 0x066, 0x44E, 0x330, 0x01C, 0x064, 0x44A, 0x335, 0x01D,
- 0x063, 0x446, 0x33A, 0x01D, 0x061, 0x442, 0x33F, 0x01E,
- 0x05F, 0x43E, 0x344, 0x01F, 0x05E, 0x43A, 0x349, 0x020,
- 0x05C, 0x436, 0x34E, 0x020, 0x05A, 0x432, 0x353, 0x021,
- 0x059, 0x42E, 0x357, 0x022, 0x057, 0x42A, 0x35C, 0x023,
- 0x056, 0x425, 0x361, 0x024, 0x054, 0x421, 0x366, 0x024,
- 0x053, 0x41D, 0x36B, 0x025, 0x051, 0x419, 0x370, 0x026,
- 0x050, 0x415, 0x374, 0x027, 0x04E, 0x410, 0x379, 0x028,
- 0x04D, 0x40C, 0x37E, 0x029, 0x04C, 0x408, 0x383, 0x02A,
- 0x04A, 0x403, 0x388, 0x02B, 0x049, 0x3FF, 0x38C, 0x02C,
- 0x047, 0x3FB, 0x391, 0x02D, 0x046, 0x3F6, 0x396, 0x02E,
- 0x045, 0x3F2, 0x39B, 0x02F, 0x043, 0x3ED, 0x39F, 0x030,
- 0x042, 0x3E9, 0x3A4, 0x031, 0x041, 0x3E5, 0x3A9, 0x032,
- 0x040, 0x3E0, 0x3AD, 0x033, 0x03E, 0x3DC, 0x3B2, 0x034,
- 0x03D, 0x3D7, 0x3B7, 0x035, 0x03C, 0x3D2, 0x3BB, 0x036,
- 0x03B, 0x3CE, 0x3C0, 0x037, 0x03A, 0x3C9, 0x3C5, 0x038,
- 0x038, 0x3C5, 0x3C9, 0x03A, 0x037, 0x3C0, 0x3CE, 0x03B,
- 0x036, 0x3BB, 0x3D2, 0x03C, 0x035, 0x3B7, 0x3D7, 0x03D,
- 0x034, 0x3B2, 0x3DC, 0x03E, 0x033, 0x3AD, 0x3E0, 0x040,
- 0x032, 0x3A9, 0x3E5, 0x041, 0x031, 0x3A4, 0x3E9, 0x042,
- 0x030, 0x39F, 0x3ED, 0x043, 0x02F, 0x39B, 0x3F2, 0x045,
- 0x02E, 0x396, 0x3F6, 0x046, 0x02D, 0x391, 0x3FB, 0x047,
- 0x02C, 0x38C, 0x3FF, 0x049, 0x02B, 0x388, 0x403, 0x04A,
- 0x02A, 0x383, 0x408, 0x04C, 0x029, 0x37E, 0x40C, 0x04D,
- 0x028, 0x379, 0x410, 0x04E, 0x027, 0x374, 0x415, 0x050,
- 0x026, 0x370, 0x419, 0x051, 0x025, 0x36B, 0x41D, 0x053,
- 0x024, 0x366, 0x421, 0x054, 0x024, 0x361, 0x425, 0x056,
- 0x023, 0x35C, 0x42A, 0x057, 0x022, 0x357, 0x42E, 0x059,
- 0x021, 0x353, 0x432, 0x05A, 0x020, 0x34E, 0x436, 0x05C,
- 0x020, 0x349, 0x43A, 0x05E, 0x01F, 0x344, 0x43E, 0x05F,
- 0x01E, 0x33F, 0x442, 0x061, 0x01D, 0x33A, 0x446, 0x063,
- 0x01D, 0x335, 0x44A, 0x064, 0x01C, 0x330, 0x44E, 0x066,
- 0x01B, 0x32B, 0x452, 0x068, 0x01B, 0x326, 0x455, 0x06A,
- 0x01A, 0x322, 0x459, 0x06B, 0x019, 0x31D, 0x45D, 0x06D,
- 0x018, 0x318, 0x461, 0x06F, 0x018, 0x313, 0x465, 0x071,
- 0x017, 0x30E, 0x468, 0x073, 0x017, 0x309, 0x46C, 0x075,
- 0x016, 0x304, 0x470, 0x076, 0x015, 0x2FF, 0x473, 0x078,
- 0x015, 0x2FA, 0x477, 0x07A, 0x014, 0x2F5, 0x47A, 0x07C,
- 0x014, 0x2F0, 0x47E, 0x07E, 0x013, 0x2EB, 0x481, 0x080,
- 0x013, 0x2E6, 0x485, 0x082, 0x012, 0x2E1, 0x488, 0x084,
- 0x011, 0x2DC, 0x48C, 0x086, 0x011, 0x2D8, 0x48F, 0x089,
- 0x010, 0x2D3, 0x492, 0x08B, 0x010, 0x2CE, 0x496, 0x08D,
- 0x00F, 0x2C9, 0x499, 0x08F, 0x00F, 0x2C4, 0x49C, 0x091,
- 0x00F, 0x2BF, 0x49F, 0x093, 0x00E, 0x2BA, 0x4A2, 0x096,
- 0x00E, 0x2B5, 0x4A6, 0x098, 0x00D, 0x2B0, 0x4A9, 0x09A,
- 0x00D, 0x2AB, 0x4AC, 0x09C, 0x00C, 0x2A6, 0x4AF, 0x09F,
- 0x00C, 0x2A2, 0x4B2, 0x0A1, 0x00B, 0x29D, 0x4B5, 0x0A3,
- 0x00B, 0x298, 0x4B7, 0x0A6, 0x00B, 0x293, 0x4BA, 0x0A8,
- 0x00A, 0x28E, 0x4BD, 0x0AB, 0x00A, 0x289, 0x4C0, 0x0AD,
- 0x00A, 0x284, 0x4C3, 0x0AF, 0x009, 0x280, 0x4C5, 0x0B2,
- 0x009, 0x27B, 0x4C8, 0x0B4, 0x009, 0x276, 0x4CB, 0x0B7,
- 0x008, 0x271, 0x4CD, 0x0BA, 0x008, 0x26C, 0x4D0, 0x0BC,
- 0x008, 0x267, 0x4D2, 0x0BF, 0x007, 0x263, 0x4D5, 0x0C1,
- 0x007, 0x25E, 0x4D7, 0x0C4, 0x007, 0x259, 0x4D9, 0x0C7,
- 0x006, 0x254, 0x4DC, 0x0C9, 0x006, 0x250, 0x4DE, 0x0CC,
- 0x006, 0x24B, 0x4E0, 0x0CF, 0x006, 0x246, 0x4E3, 0x0D2,
- 0x005, 0x241, 0x4E5, 0x0D4, 0x005, 0x23D, 0x4E7, 0x0D7,
- 0x005, 0x238, 0x4E9, 0x0DA, 0x005, 0x233, 0x4EB, 0x0DD,
- 0x004, 0x22F, 0x4ED, 0x0E0, 0x004, 0x22A, 0x4EF, 0x0E3,
- 0x004, 0x226, 0x4F1, 0x0E6, 0x004, 0x221, 0x4F3, 0x0E9,
- 0x004, 0x21C, 0x4F5, 0x0EC, 0x003, 0x218, 0x4F6, 0x0EF,
- 0x003, 0x213, 0x4F8, 0x0F2, 0x003, 0x20F, 0x4FA, 0x0F5,
- 0x003, 0x20A, 0x4FB, 0x0F8, 0x003, 0x205, 0x4FD, 0x0FB,
- 0x002, 0x201, 0x4FF, 0x0FE, 0x002, 0x1FC, 0x500, 0x101,
- 0x002, 0x1F8, 0x502, 0x104, 0x002, 0x1F3, 0x503, 0x107,
- 0x002, 0x1EF, 0x504, 0x10B, 0x002, 0x1EB, 0x506, 0x10E,
- 0x002, 0x1E6, 0x507, 0x111, 0x001, 0x1E2, 0x508, 0x114,
- 0x001, 0x1DD, 0x50A, 0x118, 0x001, 0x1D9, 0x50B, 0x11B,
- 0x001, 0x1D5, 0x50C, 0x11E, 0x001, 0x1D0, 0x50D, 0x122,
- 0x001, 0x1CC, 0x50E, 0x125, 0x001, 0x1C8, 0x50F, 0x129,
- 0x001, 0x1C3, 0x510, 0x12C, 0x001, 0x1BF, 0x511, 0x130,
- 0x001, 0x1BB, 0x511, 0x133, 0x001, 0x1B7, 0x512, 0x137,
- 0x000, 0x1B2, 0x513, 0x13A, 0x000, 0x1AE, 0x514, 0x13E,
- 0x000, 0x1AA, 0x514, 0x141, 0x000, 0x1A6, 0x515, 0x145,
- 0x000, 0x1A2, 0x516, 0x148, 0x000, 0x19E, 0x516, 0x14C,
- 0x000, 0x19A, 0x517, 0x150, 0x000, 0x195, 0x517, 0x153,
- 0x000, 0x191, 0x517, 0x157, 0x000, 0x18D, 0x518, 0x15B,
- 0x000, 0x189, 0x518, 0x15F, 0x000, 0x185, 0x518, 0x162,
- 0x000, 0x181, 0x518, 0x166, 0x000, 0x17D, 0x518, 0x16A,
- 0x000, 0x17A, 0x519, 0x16E, 0x000, 0x176, 0x519, 0x172
- };
- void SPUwriteRegister(unsigned long reg, unsigned short val)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << setfill('0');
- std::cout << "*** SPUwriteRegister() " << "[address 0x"
- << hex << setw(8) << reg << "] ";
- #endif
- const unsigned long r = reg & 0xfff;
- regArea[(r - 0xc00) >> 1] = val;
- // some channel info?
- if(r >= 0x0c00 && r < 0x0d80)
- {
- // calc channel
- int ch = (r >> 4) - 0xc0;
- switch(r & 0x0f)
- {
- // l volume
- case 0:
- #ifdef DEBUG_OUTPUT
- std::cout << "Left Volume - ";
- #endif
- SetVolumeL((unsigned char)ch, val);
- break;
- // r volume
- case 2:
- #ifdef DEBUG_OUTPUT
- std::cout << "Right Volume - ";
- #endif
- SetVolumeR((unsigned char)ch, val);
- break;
- // pitch
- case 4:
- #ifdef DEBUG_OUTPUT
- std::cout << "Pitch - ";
- #endif
- SetPitch(ch, val);
- break;
- // start
- case 6:
- #ifdef DEBUG_OUTPUT
- std::cout << "Start Address - ";
- #endif
- s_chan[ch].pStart = spuMemC + ((unsigned long)val << 3);
- break;
- // level with pre-calcs
- case 8:
- #ifdef DEBUG_OUTPUT
- std::cout << "Level with Pre-Calcs - ";
- #endif
- {
- const unsigned long lval = val;
- s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0;
- s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f;
- s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f;
- s_chan[ch].ADSRX.SustainLevel=lval & 0x000f;
- }
- break;
- // adsr times with pre-calcs
- case 10:
- #ifdef DEBUG_OUTPUT
- std::cout << "ADSR Times with Pre-Calcs - ";
- #endif
- {
- const unsigned long lval = val;
- s_chan[ch].ADSRX.SustainModeExp = (lval & 0x8000) ? 1 : 0;
- s_chan[ch].ADSRX.SustainIncrease = (lval & 0x4000) ? 0 : 1;
- s_chan[ch].ADSRX.SustainRate = (lval >> 6) & 0x007f;
- s_chan[ch].ADSRX.ReleaseModeExp = (lval & 0x0020) ? 1 : 0;
- s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f;
- }
- break;
- // adsr volume... mmm have to investigate this
- case 12:
- #ifdef DEBUG_OUTPUT
- std::cout << "ADSR Volume - ";
- #endif
- break;
- // loop
- case 14:
- #ifdef DEBUG_OUTPUT
- std::cout << "Loop Address - ";
- #endif
- s_chan[ch].pLoop = spuMemC + ((unsigned long)val << 3);
- s_chan[ch].bIgnoreLoop = 1;
- break;
- }
- iWatchDog = 0;
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << val << std::endl;
- #endif
- return;
- }
- switch(r)
- {
- case H_SPUaddr:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUaddr - ";
- #endif
- spuAddr = (unsigned long)val << 3;
- break;
- case H_SPUdata:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUdata - ";
- #endif
- spuMem[spuAddr >> 1] = val;
- spuAddr += 2;
- if(spuAddr > 0x7ffff)
- spuAddr = 0;
- break;
- case H_SPUctrl:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUctrl - ";
- #endif
- spuCtrl = val;
- break;
- case H_SPUstat:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUstat - ";
- #endif
- spuStat = val & 0xf800;
- break;
- case H_SPUReverbAddr:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUReverbAddr - ";
- #endif
- if(val == 0xFFFF || val <= 0x200)
- rvb.StartAddr = rvb.CurrAddr = 0;
- else
- {
- const long iv = (unsigned long)val << 2;
- if(rvb.StartAddr != iv)
- {
- rvb.StartAddr = (unsigned long)val << 2;
- rvb.CurrAddr = rvb.StartAddr;
- }
- }
- break;
- case H_SPUirqAddr:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUirqAddr - ";
- #endif
- spuIrq = val;
- pSpuIrq = spuMemC + ((unsigned long) val << 3);
- break;
- case H_SPUrvolL:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUrvolL - ";
- #endif
- rvb.VolLeft = val;
- break;
- case H_SPUrvolR:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUrvolR - ";
- #endif
- rvb.VolRight = val;
- break;
- case H_SPUon1:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUon1 - ";
- #endif
- SoundOn(0, 16, val);
- break;
- case H_SPUon2:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUon2 - ";
- #endif
- SoundOn(16, 24, val);
- break;
- case H_SPUoff1:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUoff1 - ";
- #endif
- SoundOff(0, 16, val);
- break;
- case H_SPUoff2:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_SPUoff2 - ";
- #endif
- SoundOff(16, 24, val);
- break;
- case H_CDLeft:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_CDLeft - ";
- #endif
- iLeftXAVol = val & 0x7fff;
- if(cddavCallback)
- cddavCallback(0, val);
- break;
- case H_CDRight:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_CDRight - ";
- #endif
- iRightXAVol = val & 0x7fff;
- if(cddavCallback)
- cddavCallback(1, val);
- break;
- case H_FMod1:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_FMod1 - ";
- #endif
- FModOn(0, 16, val);
- break;
- case H_FMod2:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_FMod2 - ";
- #endif
- FModOn(16, 24, val);
- break;
- case H_Noise1:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_Noise1 - ";
- #endif
- NoiseOn(0, 16, val);
- break;
- case H_Noise2:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_Noise2 - ";
- #endif
- NoiseOn(16, 24, val);
- break;
- case H_RVBon1:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_RVBon1 - ";
- #endif
- ReverbOn(0, 16, val);
- break;
- case H_RVBon2:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_RVBon2 - ";
- #endif
- ReverbOn(16, 24, val);
- break;
- case H_Reverb + 0:
- #ifdef DEBUG_OUTPUT
- std::cout << "H_Reverb - ";
- #endif
- rvb.FB_SRC_A = val;
- // OK, here's the fake REVERB stuff...
- // depending on effect we do more or less delay and repeats... bah
- // still... better than nothing :)
- SetREVERB(val);
- break;
- case H_Reverb+2 : rvb.FB_SRC_B=(short)val; break;
- case H_Reverb+4 : rvb.IIR_ALPHA=(short)val; break;
- case H_Reverb+6 : rvb.ACC_COEF_A=(short)val; break;
- case H_Reverb+8 : rvb.ACC_COEF_B=(short)val; break;
- case H_Reverb+10 : rvb.ACC_COEF_C=(short)val; break;
- case H_Reverb+12 : rvb.ACC_COEF_D=(short)val; break;
- case H_Reverb+14 : rvb.IIR_COEF=(short)val; break;
- case H_Reverb+16 : rvb.FB_ALPHA=(short)val; break;
- case H_Reverb+18 : rvb.FB_X=(short)val; break;
- case H_Reverb+20 : rvb.IIR_DEST_A0=(short)val; break;
- case H_Reverb+22 : rvb.IIR_DEST_A1=(short)val; break;
- case H_Reverb+24 : rvb.ACC_SRC_A0=(short)val; break;
- case H_Reverb+26 : rvb.ACC_SRC_A1=(short)val; break;
- case H_Reverb+28 : rvb.ACC_SRC_B0=(short)val; break;
- case H_Reverb+30 : rvb.ACC_SRC_B1=(short)val; break;
- case H_Reverb+32 : rvb.IIR_SRC_A0=(short)val; break;
- case H_Reverb+34 : rvb.IIR_SRC_A1=(short)val; break;
- case H_Reverb+36 : rvb.IIR_DEST_B0=(short)val; break;
- case H_Reverb+38 : rvb.IIR_DEST_B1=(short)val; break;
- case H_Reverb+40 : rvb.ACC_SRC_C0=(short)val; break;
- case H_Reverb+42 : rvb.ACC_SRC_C1=(short)val; break;
- case H_Reverb+44 : rvb.ACC_SRC_D0=(short)val; break;
- case H_Reverb+46 : rvb.ACC_SRC_D1=(short)val; break;
- case H_Reverb+48 : rvb.IIR_SRC_B1=(short)val; break;
- case H_Reverb+50 : rvb.IIR_SRC_B0=(short)val; break;
- case H_Reverb+52 : rvb.MIX_DEST_A0=(short)val; break;
- case H_Reverb+54 : rvb.MIX_DEST_A1=(short)val; break;
- case H_Reverb+56 : rvb.MIX_DEST_B0=(short)val; break;
- case H_Reverb+58 : rvb.MIX_DEST_B1=(short)val; break;
- case H_Reverb+60 : rvb.IN_COEF_L=(short)val; break;
- case H_Reverb+62 : rvb.IN_COEF_R=(short)val; break;
- }
- iWatchDog = 0;
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << val << std::endl;
- #endif
- }
- unsigned short SPUreadRegister(unsigned long reg)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << setfill('0');
- std::cout << "*** SPUreadRegister(0x" << hex << setw(8) << reg << "), returned ";
- #endif
- const unsigned long r = reg & 0xfff;
- iWatchDog = 0;
- if(r >= 0x0c00 && r < 0x0d80)
- {
- switch(r & 0x0f)
- {
- // get adsr vol
- case 12:
- {
- const int ch = (r >> 4) - 0xc0;
- // we are started, but not processed? return 1
- if(s_chan[ch].bNew)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << 1 << std::endl;
- #endif
- return 1;
- }
- // same here... we haven't decoded one sample
- // yet, so no envelope yet. return 1 as well
- if(s_chan[ch].ADSRX.lVolume &&
- !s_chan[ch].ADSRX.EnvelopeVol)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << 1 << std::endl;
- #endif
- return 1;
- }
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4)
- << (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol >> 16)
- << std::endl;
- #endif
- return (unsigned short)(s_chan[ch].ADSRX.EnvelopeVol >> 16);
- }
- // get loop address
- case 14:
- {
- const int ch = (r >> 4) - 0xc0;
- if(s_chan[ch].pLoop == NULL)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << 0 << std::endl;
- #endif
- return 0;
- }
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4)
- << (unsigned short)((s_chan[ch].pLoop - spuMemC) >> 3)
- << std::endl;
- #endif
- return (unsigned short)((s_chan[ch].pLoop - spuMemC) >> 3);
- }
- }
- }
- switch(r)
- {
- case H_SPUctrl:
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << spuCtrl << std::endl;
- #endif
- return spuCtrl;
- case H_SPUstat:
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << spuStat << std::endl;
- #endif
- return spuStat;
- case H_SPUaddr:
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex
- << setw(4) << (unsigned short)(spuAddr >> 3) << std::endl;
- #endif
- return (unsigned short)(spuAddr >> 3);
- case H_SPUdata:
- {
- unsigned short s = spuMem[spuAddr >> 1];
- spuAddr += 2;
- if(spuAddr > 0x7ffff)
- spuAddr = 0;
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << s << std::endl;
- #endif
- return s;
- }
- case H_SPUirqAddr:
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << spuIrq << std::endl;
- #endif
- return spuIrq;
- }
- #ifdef DEBUG_OUTPUT
- std::cout << "0x" << hex << setw(4) << regArea[(r - 0xc00) >> 1] << std::endl;
- #endif
- return regArea[(r - 0xc00) >> 1];
- }
- void SoundOn(int start, int end, unsigned short val)
- {
- int ch;
- // loop channels
- for(ch = start; ch < end; ch++, val >>= 1)
- {
- if((val & 1) && s_chan[ch].pStart)
- // mmm... start has to be set before key on !?!
- {
- s_chan[ch].bIgnoreLoop = 0;
- s_chan[ch].bNew = 1;
- // bitfield for faster testing
- dwNewChannel |= (1 << ch);
- }
- }
- }
- void SoundOff(int start, int end, unsigned short val)
- {
- int ch;
- // loop channels
- for(ch = start; ch < end; ch++, val >>= 1)
- {
- if(val & 1) // && s_chan[i].bOn) mmm...
- s_chan[ch].bStop = 1;
- }
- }
- void FModOn(int start, int end, unsigned short val)
- {
- int ch;
- // loop channels
- for(ch = start; ch < end; ch++, val >>= 1)
- {
- // fmod on/off
- if(val & 1)
- {
- if(ch > 0)
- {
- // sound channel
- s_chan[ch].bFMod = 1;
- // freq channel
- s_chan[ch - 1].bFMod = 2;
- }
- }
- else
- s_chan[ch].bFMod = 0;
- }
- }
- void NoiseOn(int start, int end, unsigned short val)
- {
- int ch;
- // loop channels
- for(ch = start; ch < end; ch++, val >>= 1)
- {
- // noise on/off
- if(val & 1)
- {
- s_chan[ch].bNoise = 1;
- }
- else
- {
- s_chan[ch].bNoise = 0;
- }
- }
- }
- // please note: sweep and phase invert are wrong... but I've never seen
- // them used
- void SetVolumeL(unsigned char ch, short vol)
- {
- s_chan[ch].iLeftVolRaw = vol;
- // sweep
- if(vol & 0x8000)
- {
- short sInc = 1;
- if(vol & 0x2000)
- sInc = -1;
- // -> mmm... phase inverted? have to investigate this
- if(vol & 0x1000)
- vol ^= 0xffff;
- // -> sweep: 0..127 -> 0..64
- vol = ((vol & 0x7f) + 1) / 2;
- // -> HACK: we don't sweep right now, so we
- // just raise/lower the volume by the half!
- vol += vol / (2 * sInc);
- vol *= 128;
- }
- // no sweep
- else
- {
- // -> mmm... phase inverted? have to investigate this
- if(vol & 0x4000)
- vol = 0x3fff - (vol & 0x3fff);
- }
- vol &= 0x3fff;
- // store volume
- s_chan[ch].iLeftVolume = vol;
- }
- void SetVolumeR(unsigned char ch, short vol)
- {
- s_chan[ch].iRightVolRaw = vol;
- // comments... see above :)
- if(vol & 0x8000)
- {
- short sInc = 1;
- if(vol & 0x2000)
- sInc = -1;
- if(vol & 0x1000)
- vol ^= 0xffff;
- vol = ((vol & 0x7f) + 1) / 2;
- vol += vol / (2 * sInc);
- vol *= 128;
- }
- else
- {
- if(vol & 0x4000)
- vol = 0x3fff - (vol & 0x3fff);
- }
- vol &= 0x3fff;
- s_chan[ch].iRightVolume = vol;
- }
- void SetPitch(int ch, unsigned short val)
- {
- int NP;
- if(val > 0x3fff)
- NP = 0x3fff;
- else
- NP = val;
- s_chan[ch].iRawPitch = NP;
- NP = (44100L * NP) / 4096L;
- if(NP < 1)
- NP = 1;
- s_chan[ch].iActFreq = NP;
- }
- void ReverbOn(int start, int end, unsigned short val)
- {
- int ch;
- // loop channels
- for(ch = start; ch < end; ch++, val >>= 1)
- {
- // reverb on/off
- if(val & 1)
- s_chan[ch].bReverb = 1;
- else
- s_chan[ch].bReverb = 0;
- }
- }
- void SetREVERB(unsigned short val)
- {
- switch(val)
- {
- // off
- case 0x0000:
- iReverbOff = -1;
- break;
- // ok room
- case 0x007D:
- iReverbOff = 32;
- iReverbNum = 2;
- iReverbRepeat = 128;
- break;
- // studio small
- case 0x0033:
- iReverbOff = 32;
- iReverbNum = 2;
- iReverbRepeat = 64;
- break;
- // ok studio medium
- case 0x00B1:
- iReverbOff = 48;
- iReverbNum = 2;
- iReverbRepeat = 96;
- break;
- // ok studio large ok
- case 0x00E3:
- iReverbOff = 64;
- iReverbNum = 2;
- iReverbRepeat = 128;
- break;
- // ok hall
- case 0x01A5:
- iReverbOff = 128;
- iReverbNum = 4;
- iReverbRepeat = 32;
- break;
- // space echo
- case 0x033D:
- iReverbOff = 256;
- iReverbNum = 4;
- iReverbRepeat = 64;
- break;
- // echo/delay
- case 0x0001:
- iReverbOff = 184;
- iReverbNum = 3;
- iReverbRepeat = 128;
- break;
- // half echo
- case 0x0017:
- iReverbOff = 128;
- iReverbNum = 2;
- iReverbRepeat = 128;
- break;
- default:
- iReverbOff = 32;
- iReverbNum = 1;
- iReverbRepeat = 0;
- break;
- }
- }
- void StartREVERB(int ch)
- {
- // reverb possible?
- if(s_chan[ch].bReverb && (spuCtrl & 0x80))
- {
- if(iUseReverb == 2)
- s_chan[ch].bRVBActive = 1;
- else
- // fake reverb used?
- if(iUseReverb == 1 && iReverbOff > 0)
- {
- // activate it
- s_chan[ch].bRVBActive = 1;
- s_chan[ch].iRVBOffset = iReverbOff * 45;
- s_chan[ch].iRVBRepeat = iReverbRepeat * 45;
- s_chan[ch].iRVBNum = iReverbNum;
- }
- }
- else
- // no reverb
- s_chan[ch].bRVBActive = 0;
- }
- void InitREVERB()
- {
- if(iUseReverb == 2)
- memset(sRVBStart, 0, NSSIZE * 2 * 4);
- }
- void StoreREVERB(int ch, int ns)
- {
- if(iUseReverb == 0)
- return;
- // Neil's reverb
- if(iUseReverb == 2)
- {
- const int iRxl =
- (s_chan[ch].sval * s_chan[ch].iLeftVolume) / 0x4000;
- const int iRxr =
- (s_chan[ch].sval * s_chan[ch].iRightVolume) / 0x4000;
- ns <<= 1;
- // -> we mix all active reverb channels into an extra buffer
- *(sRVBStart + ns) += iRxl;
- *(sRVBStart + ns + 1) += iRxr;
- }
- // Pete's easy fake reverb
- else
- {
- int *pN;
- int iRn, iRr = 0;
- // we use the half channel volume (/0x8000) for the
- // first reverb effects, quarter for next and so on
- int iRxl =
- (s_chan[ch].sval * s_chan[ch].iLeftVolume) / 0x8000;
- int iRxr =
- (s_chan[ch].sval * s_chan[ch].iRightVolume) / 0x8000;
- for(iRn = 1; iRn <= s_chan[ch].iRVBNum;
- iRn++, iRr += s_chan[ch].iRVBRepeat,iRxl /= 2, iRxr /= 2)
- {
- pN = sRVBPlay + ((s_chan[ch].iRVBOffset + iRr + ns) << 1);
- if(pN >= sRVBEnd)
- pN = sRVBStart + (pN - sRVBEnd);
- (*pN) += iRxl;
- pN++;
- (*pN) += iRxr;
- }
- }
- }
- // get_buffer content helper: takes care about wraps
- int g_buffer(int iOff)
- {
- short *p = (short *)spuMem;
- iOff = (iOff * 4) + rvb.CurrAddr;
- while(iOff > 0x3FFFF)
- iOff = rvb.StartAddr + (iOff - 0x40000);
- while(iOff < rvb.StartAddr)
- iOff = 0x3ffff - (rvb.StartAddr - iOff);
- return (int)*(p + iOff);
- }
- // set_buffer content helper: takes care about wraps and clipping
- void s_buffer(int iOff, int iVal)
- {
- short *p = (short *)spuMem;
- iOff = (iOff * 4) + rvb.CurrAddr;
- while(iOff > 0x3FFFF)
- iOff = rvb.StartAddr + (iOff - 0x40000);
- while(iOff < rvb.StartAddr)
- iOff = 0x3ffff - (rvb.StartAddr - iOff);
- if(iVal < -32768L)
- iVal = -32768L;
- if(iVal > 32767L)
- iVal = 32767L;
- *(p + iOff) = (short)iVal;
- }
- // set_buffer (+1 sample) content helper: takes care about wraps and clipping
- void s_buffer1(int iOff, int iVal)
- {
- short *p = (short *)spuMem;
- iOff = (iOff * 4) + rvb.CurrAddr + 1;
- while(iOff > 0x3FFFF)
- iOff = rvb.StartAddr + (iOff - 0x40000);
- while(iOff < rvb.StartAddr)
- iOff = 0x3ffff - (rvb.StartAddr - iOff);
- if(iVal < -32768L)
- iVal = -32768L;
- if(iVal > 32767L)
- iVal = 32767L;
- *(p + iOff) = (short)iVal;
- }
- int MixREVERBLeft(int ns)
- {
- if(iUseReverb == 0)
- return 0;
- if(iUseReverb == 2)
- {
- // this func will be called with 44.1 khz
- static int iCnt = 0;
- // reverb is off
- if(!rvb.StartAddr)
- {
- rvb.iLastRVBLeft = rvb.iLastRVBRight =
- rvb.iRVBLeft = rvb.iRVBRight = 0;
- return 0;
- }
- iCnt++;
- // we work on every second left value: downsample to 22 khz
- if(iCnt & 1)
- {
- // -> reverb on? oki
- if(spuCtrl & 0x80)
- {
- int ACC0, ACC1, FB_A0, FB_A1, FB_B0, FB_B1;
- const int INPUT_SAMPLE_L = *(sRVBStart + (ns << 1));
- const int INPUT_SAMPLE_R = *(sRVBStart + (ns << 1) + 1);
- const int IIR_INPUT_A0 =
- (g_buffer(rvb.IIR_SRC_A0) * rvb.IIR_COEF) / 32768L +
- (INPUT_SAMPLE_L * rvb.IN_COEF_L) / 32768L;
- const int IIR_INPUT_A1 =
- (g_buffer(rvb.IIR_SRC_A1) * rvb.IIR_COEF) / 32768L +
- (INPUT_SAMPLE_R * rvb.IN_COEF_R) / 32768L;
- const int IIR_INPUT_B0 =
- (g_buffer(rvb.IIR_SRC_B0) * rvb.IIR_COEF) / 32768L +
- (INPUT_SAMPLE_L * rvb.IN_COEF_L) / 32768L;
- const int IIR_INPUT_B1 =
- (g_buffer(rvb.IIR_SRC_B1) * rvb.IIR_COEF) / 32768L +
- (INPUT_SAMPLE_R * rvb.IN_COEF_R) / 32768L;
- const int IIR_A0 = (IIR_INPUT_A0 * rvb.IIR_ALPHA) / 32768L +
- (g_buffer(rvb.IIR_DEST_A0) *
- (32768L - rvb.IIR_ALPHA)) / 32768L;
- const int IIR_A1 = (IIR_INPUT_A1 * rvb.IIR_ALPHA) / 32768L +
- (g_buffer(rvb.IIR_DEST_A1) *
- (32768L - rvb.IIR_ALPHA)) / 32768L;
- const int IIR_B0 = (IIR_INPUT_B0 * rvb.IIR_ALPHA) / 32768L +
- (g_buffer(rvb.IIR_DEST_B0) *
- (32768L - rvb.IIR_ALPHA)) / 32768L;
- const int IIR_B1 = (IIR_INPUT_B1 * rvb.IIR_ALPHA) / 32768L +
- (g_buffer(rvb.IIR_DEST_B1) *
- (32768L - rvb.IIR_ALPHA)) / 32768L;
- s_buffer1(rvb.IIR_DEST_A0, IIR_A0);
- s_buffer1(rvb.IIR_DEST_A1, IIR_A1);
- s_buffer1(rvb.IIR_DEST_B0, IIR_B0);
- s_buffer1(rvb.IIR_DEST_B1, IIR_B1);
- ACC0 = (g_buffer(rvb.ACC_SRC_A0) * rvb.ACC_COEF_A) / 32768L +
- (g_buffer(rvb.ACC_SRC_B0) * rvb.ACC_COEF_B) / 32768L +
- (g_buffer(rvb.ACC_SRC_C0) * rvb.ACC_COEF_C) / 32768L +
- (g_buffer(rvb.ACC_SRC_D0) * rvb.ACC_COEF_D) / 32768L;
- ACC1 = (g_buffer(rvb.ACC_SRC_A1) * rvb.ACC_COEF_A) / 32768L +
- (g_buffer(rvb.ACC_SRC_B1) * rvb.ACC_COEF_B) / 32768L +
- (g_buffer(rvb.ACC_SRC_C1) * rvb.ACC_COEF_C) / 32768L +
- (g_buffer(rvb.ACC_SRC_D1) * rvb.ACC_COEF_D) / 32768L;
- FB_A0 = g_buffer(rvb.MIX_DEST_A0 - rvb.FB_SRC_A);
- FB_A1 = g_buffer(rvb.MIX_DEST_A1 - rvb.FB_SRC_A);
- FB_B0 = g_buffer(rvb.MIX_DEST_B0 - rvb.FB_SRC_B);
- FB_B1 = g_buffer(rvb.MIX_DEST_B1 - rvb.FB_SRC_B);
- s_buffer(rvb.MIX_DEST_A0,
- ACC0 - (FB_A0 * rvb.FB_ALPHA) / 32768L);
- s_buffer(rvb.MIX_DEST_A1,
- ACC1 - (FB_A1 * rvb.FB_ALPHA) / 32768L);
- s_buffer(rvb.MIX_DEST_B0, (rvb.FB_ALPHA * ACC0) / 32768L -
- (FB_A0 * (int)(rvb.FB_ALPHA ^ 0xFFFF8000)) / 32768L -
- (FB_B0 * rvb.FB_X) / 32768L);
- s_buffer(rvb.MIX_DEST_B1, (rvb.FB_ALPHA * ACC1) / 32768L -
- (FB_A1 * (int)(rvb.FB_ALPHA ^ 0xFFFF8000)) / 32768L -
- (FB_B1 * rvb.FB_X) / 32768L);
- rvb.iLastRVBLeft = rvb.iRVBLeft;
- rvb.iLastRVBRight = rvb.iRVBRight;
- rvb.iRVBLeft =
- (g_buffer(rvb.MIX_DEST_A0) + g_buffer(rvb.MIX_DEST_B0)) / 3;
- rvb.iRVBRight =
- (g_buffer(rvb.MIX_DEST_A1) + g_buffer(rvb.MIX_DEST_B1)) / 3;
- rvb.iRVBLeft = (rvb.iRVBLeft * rvb.VolLeft) / 0x4000;
- rvb.iRVBRight = (rvb.iRVBRight * rvb.VolRight) / 0x4000;
- rvb.CurrAddr++;
- if(rvb.CurrAddr > 0x3ffff)
- rvb.CurrAddr = rvb.StartAddr;
- return rvb.iLastRVBLeft + (rvb.iRVBLeft-rvb.iLastRVBLeft) / 2;
- }
- // reverb off
- else
- rvb.iLastRVBLeft = rvb.iLastRVBRight =
- rvb.iRVBLeft = rvb.iRVBRight = 0;
- rvb.CurrAddr++;
- if(rvb.CurrAddr > 0x3ffff)
- rvb.CurrAddr = rvb.StartAddr;
- }
- return rvb.iLastRVBLeft;
- }
- // easy fake reverb
- else
- {
- // -> simply take the reverb mix buf value
- const int iRV = *sRVBPlay;
- // -> init it after
- *sRVBPlay++ = 0;
- // -> and take care about wrap arounds
- if(sRVBPlay >= sRVBEnd)
- sRVBPlay = sRVBStart;
- // -> return reverb buf mix val
- return iRV;
- }
- }
- int MixREVERBRight()
- {
- if(iUseReverb == 0)
- return 0;
- // Neill's reverb
- if(iUseReverb == 2)
- {
- int i = rvb.iLastRVBRight + (rvb.iRVBRight - rvb.iLastRVBRight) / 2;
- rvb.iLastRVBRight = rvb.iRVBRight;
- // -> just return the last right reverb val
- // (little bit scaled by the previous right val)
- return i;
- }
- // easy fake reverb
- else
- {
- // -> simply take the reverb mix buf value
- const int iRV = *sRVBPlay;
- // -> init it after
- *sRVBPlay++ = 0;
- // -> and take care about wrap arounds
- if(sRVBPlay >= sRVBEnd)
- sRVBPlay = sRVBStart;
- // -> return reverb mix buf val
- return iRV;
- }
- }
- void MixXA()
- {
- int ns;
- for(ns = 0; ns < NSSIZE && XAPlay != XAFeed; ns++)
- {
- XALastVal = *XAPlay++;
- if(XAPlay == XAEnd)
- XAPlay = XAStart;
- SSumL[ns] += (((short)(XALastVal & 0xffff)) * iLeftXAVol) / 32767;
- SSumR[ns] += (((short)((XALastVal >> 16) & 0xffff)) *
- iRightXAVol) / 32767;
- }
- if(XAPlay == XAFeed && XARepeat)
- {
- XARepeat--;
- for(;ns < NSSIZE; ns++)
- {
- SSumL[ns] += (((short)(XALastVal & 0xffff)) * iLeftXAVol) / 32767;
- SSumR[ns] += (((short)((XALastVal >> 16) & 0xffff)) *
- iRightXAVol) / 32767;
- }
- }
- }
- void FeedXA(xa_decode_t *xap)
- {
- #ifdef VGears_SOUND
- int sinc, spos, i, iSize, iPlace, vl, vr;
- if(!bSPUIsOpen)
- return;
- // store info for save states
- xapGlobal = xap;
- // set up repeat
- XARepeat = 100;
- // get size
- iSize = ((44100 * xap->nsamples) / xap->freq);
- // if none
- if(!iSize)
- return;
- // how much space in my buf?
- if(XAFeed < XAPlay)
- iPlace = XAPlay - XAFeed;
- else
- iPlace = (XAEnd - XAFeed) + (XAPlay - XAStart);
- // no place at all
- if(iPlace == 0)
- return;
- // pitch change option
- if(iXAPitch)
- {
- static unsigned long dwLT = 0;
- static unsigned long dwFPS = 0;
- static int iFPSCnt = 0;
- static int iLastSize = 0;
- static unsigned long dwL1 = 0;
- unsigned long dw, dw1, dw2;
- //G dw = timeGetTime_spu();
- dw = GGetTime();
- iPlace = iSize;
- dwFPS += dw - dwLT;
- iFPSCnt++;
- dwLT = dw;
- if(iFPSCnt >= 10)
- {
- if(!dwFPS)
- dwFPS = 1;
- dw1 = 1000000 / dwFPS;
- if(dw1 >= (dwL1 - 100) && dw1 <= (dwL1 + 100))
- dw1 = dwL1;
- else
- dwL1 = dw1;
- dw2 = (xap->freq * 100 / xap->nsamples);
- if((!dw1) || ((dw2 + 100) >= dw1))
- iLastSize = 0;
- else
- {
- iLastSize = iSize * dw2 / dw1;
- if(iLastSize > iPlace)
- iLastSize = iPlace;
- iSize = iLastSize;
- }
- iFPSCnt = 0;
- dwFPS = 0;
- }
- else
- {
- if(iLastSize)
- iSize = iLastSize;
- }
- }
- spos = 0x10000L;
- // calc freq by num / size
- sinc = (xap->nsamples << 16) / iSize;
- if(xap->stereo)
- {
- u32 * pS = (u32 *)xap->pcm;
- u32 l = 0;
- if(iXAPitch)
- {
- int32_t l1, l2;
- short s;
- for(i = 0; i < iSize; i++)
- {
- if(iUseInterpolation == 2)
- {
- while(spos >= 0x10000L)
- {
- l = *pS++;
- gauss_window[gauss_ptr] = (short)LOWORD(l);
- gauss_window[4 + gauss_ptr] = (short)HIWORD(l);
- gauss_ptr = (gauss_ptr + 1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr = (gauss[vl]*gvall0) & ~2047;
- vr += (gauss[vl + 1] * gvall(1)) & ~2047;
- vr += (gauss[vl + 2] * gvall(2)) & ~2047;
- vr += (gauss[vl + 3] * gvall(3)) & ~2047;
- l= (vr >> 11) & 0xffff;
- vr = (gauss[vl] * gvalr0) & ~2047;
- vr += (gauss[vl + 1] * gvalr(1)) & ~2047;
- vr += (gauss[vl + 2] * gvalr(2)) & ~2047;
- vr += (gauss[vl + 3] * gvalr(3)) & ~2047;
- l |= vr << 5;
- }
- else
- {
- while(spos >= 0x10000L)
- {
- l = *pS++;
- spos -= 0x10000L;
- }
- }
- s = (short)LOWORD(l);
- l1 = s;
- l1 = (l1 * iPlace) / iSize;
- if(l1 < -32767)
- l1 = -32767;
- if(l1 > 32767)
- l1 = 32767;
- s = (short)HIWORD(l);
- l2 = s;
- l2 = (l2 * iPlace) / iSize;
- if(l2 < -32767)
- l2 = -32767;
- if(l2 > 32767)
- l2 = 32767;
- l = (l1 & 0xffff)|(l2 << 16);
- *XAFeed++ = l;
- if(XAFeed == XAEnd)
- XAFeed = XAStart;
- if(XAFeed == XAPlay)
- {
- if(XAPlay != XAStart)
- XAFeed = XAPlay - 1;
- break;
- }
- spos += sinc;
- }
- }
- else
- {
- for(i = 0; i < iSize; i++)
- {
- if(iUseInterpolation == 2)
- {
- while(spos >= 0x10000L)
- {
- l = *pS++;
- gauss_window[gauss_ptr] = (short)LOWORD(l);
- gauss_window[4 + gauss_ptr] = (short)HIWORD(l);
- gauss_ptr = (gauss_ptr + 1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr = (gauss[vl] * gvall0) & ~2047;
- vr += (gauss[vl + 1] * gvall(1)) & ~2047;
- vr += (gauss[vl + 2] * gvall(2)) & ~2047;
- vr += (gauss[vl + 3] * gvall(3)) & ~2047;
- l = (vr >> 11) & 0xffff;
- vr = (gauss[vl] * gvalr0) & ~2047;
- vr += (gauss[vl + 1] * gvalr(1)) & ~2047;
- vr += (gauss[vl + 2] * gvalr(2)) & ~2047;
- vr += (gauss[vl + 3] * gvalr(3)) & ~2047;
- l |= vr << 5;
- }
- else
- {
- while(spos>=0x10000L)
- {
- l = *pS++;
- spos -= 0x10000L;
- }
- }
- *XAFeed++ = l;
- if(XAFeed == XAEnd)
- XAFeed = XAStart;
- if(XAFeed == XAPlay)
- {
- if(XAPlay != XAStart)
- XAFeed = XAPlay - 1;
- break;
- }
- spos += sinc;
- }
- }
- }
- else
- {
- unsigned short * pS = (unsigned short *)xap->pcm;
- u32 l;
- short s = 0;
- if(iXAPitch)
- {
- int32_t l1;
- for(i = 0; i < iSize; i++)
- {
- if(iUseInterpolation == 2)
- {
- while(spos >= 0x10000L)
- {
- gauss_window[gauss_ptr] = (short)*pS++;
- gauss_ptr = (gauss_ptr + 1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr = (gauss[vl] * gvall0) & ~2047;
- vr += (gauss[vl + 1] * gvall(1)) & ~2047;
- vr += (gauss[vl + 2] * gvall(2)) & ~2047;
- vr += (gauss[vl + 3] * gvall(3)) & ~2047;
- l1 = s = vr >> 11;
- l1 &= 0xffff;
- }
- else
- {
- while(spos >= 0x10000L)
- {
- s = *pS++;
- spos -= 0x10000L;
- }
- l1 = s;
- }
- l1 = (l1 * iPlace) / iSize;
- if(l1 < -32767)
- l1 = -32767;
- if(l1 > 32767)
- l1 = 32767;
- l = (l1 & 0xffff) | (l1 << 16);
- *XAFeed++ = l;
- if(XAFeed == XAEnd)
- XAFeed = XAStart;
- if(XAFeed == XAPlay)
- {
- if(XAPlay != XAStart)
- XAFeed = XAPlay - 1;
- break;
- }
- spos += sinc;
- }
- }
- else
- {
- for(i = 0; i < iSize; i++)
- {
- if(iUseInterpolation == 2)
- {
- while(spos >= 0x10000L)
- {
- gauss_window[gauss_ptr] = (short)*pS++;
- gauss_ptr = (gauss_ptr + 1) & 3;
- spos -= 0x10000L;
- }
- vl = (spos >> 6) & ~3;
- vr = (gauss[vl] * gvall0) & ~2047;
- vr += (gauss[vl + 1] * gvall(1)) & ~2047;
- vr += (gauss[vl + 2] * gvall(2)) & ~2047;
- vr += (gauss[vl + 3] * gvall(3)) & ~2047;
- l= s = vr >> 11;
- l &= 0xffff;
- }
- else
- {
- while(spos >= 0x10000L)
- {
- s = *pS++;
- spos -= 0x10000L;
- }
- l = s;
- }
- *XAFeed++ = (l | (l << 16));
- if(XAFeed == XAEnd)
- XAFeed = XAStart;
- if(XAFeed == XAPlay)
- {
- if(XAPlay != XAStart)
- XAFeed = XAPlay - 1;
- break;
- }
- spos += sinc;
- }
- }
- }
- #endif
- }
- void InterpolateUp(int ch)
- {
- if(s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass
- {
- const int id1=s_chan[ch].SB[30]-s_chan[ch].SB[29]; // curr delta to next val
- const int id2=s_chan[ch].SB[31]-s_chan[ch].SB[30]; // and next delta to next-next val :)
- s_chan[ch].SB[32]=0;
- if(id1>0) // curr delta positive
- {
- if(id2<id1)
- {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
- else
- if(id2<(id1<<1))
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
- else
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
- }
- else // curr delta negative
- {
- if(id2>id1)
- {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
- else
- if(id2>(id1<<1))
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
- else
- s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
- }
- }
- else
- if(s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass
- {
- s_chan[ch].SB[32]=0;
- s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L;
- if(s_chan[ch].sinc<=0x8000)
- s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1));
- else s_chan[ch].SB[29]+=s_chan[ch].SB[28];
- }
- else // no flags? add bigger val (if possible), calc smaller step, set flag1
- s_chan[ch].SB[29]+=s_chan[ch].SB[28];
- }
- //
- // even easier interpolation on downsampling, also no special filter, again just "Pete's common sense" tm
- //
- void InterpolateDown(int ch)
- {
- if(s_chan[ch].sinc>=0x20000L) // we would skip at least one val?
- {
- s_chan[ch].SB[29]+=(s_chan[ch].SB[30]-s_chan[ch].SB[29])/2; // add easy weight
- if(s_chan[ch].sinc>=0x30000L) // we would skip even more vals?
- s_chan[ch].SB[29]+=(s_chan[ch].SB[31]-s_chan[ch].SB[30])/2;// add additional next weight
- }
- }
- ////////////////////////////////////////////////////////////////////////
- // helpers for gauss interpolation
- #define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos])
- #define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
- //#include "gauss_i.h"
- ////////////////////////////////////////////////////////////////////////
- //#include "xa.c"
- ////////////////////////////////////////////////////////////////////////
- // START SOUND... called by main thread to setup a new sound on a channel
- ////////////////////////////////////////////////////////////////////////
- void StartSound(int ch)
- {
- StartADSR(ch);
- StartREVERB(ch);
- s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
- s_chan[ch].s_1=0; // init mixing vars
- s_chan[ch].s_2=0;
- s_chan[ch].iSBPos=28;
- s_chan[ch].bNew=0; // init channel flags
- s_chan[ch].bStop=0;
- s_chan[ch].bOn=1;
- s_chan[ch].SB[29]=0; // init our interpolation helpers
- s_chan[ch].SB[30]=0;
- if(iUseInterpolation>=2) // gauss interpolation?
- {s_chan[ch].spos=0x30000L;s_chan[ch].SB[28]=0;} // -> start with more decoding
- else {s_chan[ch].spos=0x10000L;s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding
- dwNewChannel&=~(1<<ch); // clear new channel bit
- }
- ////////////////////////////////////////////////////////////////////////
- // MAIN SPU FUNCTION
- // here is the main job handler... thread, timer or direct func call
- // basically the whole sound processing is done in this fat func!
- ////////////////////////////////////////////////////////////////////////
- // 5 ms waiting phase, if buffer is full and no new sound has to get started
- // .. can be made smaller (smallest val: 1 ms), but bigger waits give
- // better performance
- #define PAUSE_W 5
- #define PAUSE_L 5000
- ////////////////////////////////////////////////////////////////////////
- static void *MAINThread(void *arg)
- {
- // std::cout << "!!!!!!!!!!!!!!!!!!!TEST!!!!!!!!!!!!!!!!!!" << std::endl;
- int s_1, s_2;
- int fa;
- int ns;
- int voldiv = iVolume;
- unsigned char *start;
- unsigned int nSample;
- int ch, predict_nr, shift_factor, flags, d, s;
- int gpos, bIRQReturn = 0;
- // until we are shutting down
- while(!bEndThread)
- {
- // ok, at the beginning we are looking if there is
- // enuff free place in the dsound/oss buffer to
- // fill in new data, or if there is a new channel to start.
- // if not, we wait (thread) or return (timer/spuasync)
- // until enuff free place is available/a new channel gets
- // started
- // new channel should start immedately?
- // (at least one bit 0 ... MAXCHANNEL is set?)
- if(dwNewChannel)
- {
- // set iSecure
- // (if it is set 5 times - that means on 5 tries a new samples
- // has been started - in a row, we will reset it, to give the
- // sound update a chance)
- iSecureStart++;
- if(iSecureStart > 5)
- iSecureStart = 0;
- }
- // 0: no new channel
- else
- iSecureStart = 0;
- // no new start? no thread end? and still enough data in sound buffer?
- while(!iSecureStart && !bEndThread &&
- (SBE->GetBytesBuffered() > TESTSIZE))
- {
- // reset secure
- iSecureStart = 0;
- // linux no-thread mode? bye
- if(iUseTimer)
- return 0;
- // else sleep for x ms (linux)
- #ifndef _MSC_VER
- usleep(PAUSE_L);
- #else
- Sleep(PAUSE_L);
- #endif
- // SDL_Delay(PAUSE_L);
- if(dwNewChannel)
- // if a new channel kicks in (or, of course,
- // sound buffer runs low), we will leave the loop
- iSecureStart = 1;
- }
- // continue from irq handling in timer mode?
- // will be -1 if no continue is pending
- if(lastch >= 0)
- {
- // -> setup all kind of vars to continue
- ch = lastch;
- ns = lastns;
- lastch = -1;
- // -> directly jump to the continue point
- goto GOON;
- }
- {
- // loop em all... we will collect 1 ms
- // of sound of each playing channel
- for(ch = 0; ch < MAXCHAN; ch++)
- {
- // start new channel
- if(s_chan[ch].bNew)
- StartSound(ch);
- // channel not playing? - next
- if(!s_chan[ch].bOn)
- continue;
- // new psx frequency?
- if(s_chan[ch].iActFreq != s_chan[ch].iUsedFreq)
- {
- // take int and calc steps
- s_chan[ch].iUsedFreq = s_chan[ch].iActFreq;
- s_chan[ch].sinc = s_chan[ch].iRawPitch << 4;
- if(!s_chan[ch].sinc)
- s_chan[ch].sinc = 1;
- // freq change in simple interpolation mode [set flag]
- if(iUseInterpolation == 1)
- s_chan[ch].SB[32] = 1;
- }
- // loop until 1 ms of data is reached
- ns = 0;
- while(ns < NSSIZE)
- {
- while(s_chan[ch].spos >= 0x10000L)
- {
- // 28 reached
- if(s_chan[ch].iSBPos == 28)
- {
- // set up the current pos
- start = s_chan[ch].pCurr;
- // special "stop" sign
- if (start == (unsigned char *)-1)
- {
- // turn everything off
- s_chan[ch].bOn = 0;
- s_chan[ch].ADSRX.lVolume = 0;
- s_chan[ch].ADSRX.EnvelopeVol = 0;
- // and done for this channel
- goto ENDX;
- }
- s_chan[ch].iSBPos = 0;
- // spu irq handler here? mmm... do it later
- s_1 = s_chan[ch].s_1;
- s_2 = s_chan[ch].s_2;
- predict_nr = (int)*start;
- start++;
- shift_factor = predict_nr & 0xf;
- predict_nr >>= 4;
- flags=(int)*start;
- start++;
- for (nSample = 0; nSample < 28; start++)
- {
- d = (int)*start;
- s = ((d & 0xf) << 12);
- if(s & 0x8000)
- s |= 0xffff0000;
- fa = (s >> shift_factor);
- fa = fa + ((s_1 * f[predict_nr][0]) >> 6) +
- ((s_2 * f[predict_nr][1]) >> 6);
- s_2 = s_1;
- s_1 = fa;
- s = ((d & 0xf0) << 8);
- s_chan[ch].SB[nSample++] = fa;
- if(s & 0x8000)
- s |= 0xffff0000;
- fa = (s >> shift_factor);
- fa = fa + ((s_1 * f[predict_nr][0]) >> 6) +
- ((s_2 * f[predict_nr][1]) >> 6);
- s_2 = s_1;
- s_1 = fa;
- s_chan[ch].SB[nSample++] = fa;
- }
- // irq check? mmm...
- // some callbacks and irq active?
- if(irqCallback && (spuCtrl & 0x40))
- {
- // irq address reached? &
- // special: irq on looping addr,
- // when stop/loop flag is set
- if((pSpuIrq > start - 16 && pSpuIrq <= start)
- ||
- ((flags & 1) &&
- (pSpuIrq > s_chan[ch].pLoop - 16 &&
- pSpuIrq <= s_chan[ch].pLoop)))
- {
- // debug flag
- s_chan[ch].iIrqDone = 1;
- // call main emu
- irqCallback();
- // option: wait after irq for main emu
- if(iSPUIRQWait)
- {
- unsigned long dwWatchTime;
- if(iUseTimer == 2)
- bIRQReturn = 1;
- else
- {
- // dwWatchTime = timeGetTime_spu() +
- // 2500;
- dwWatchTime = GGetTime() +
- 2500;
- iWatchDog = 1;
- while(iWatchDog && !bEndThread &&
- GGetTime() < dwWatchTime)
- #ifndef _MSC_VER
- usleep(10);
- #else
- Sleep(10);
- #endif
- // SDL_Delay(1000L);
- }
- }
- }
- }
- // flag handler
- // loop address
- if((flags & 4) && (!s_chan[ch].bIgnoreLoop))
- s_chan[ch].pLoop = start - 16;
- // stop loop
- if(flags & 1)
- {
- // PETE: if we don't check exactly for 3,
- // loop hang ups will happen (DQ4, for example)
- if(flags != 3 || s_chan[ch].pLoop == NULL)
- {
- // and checking if pLoop is
- // set avoids crashes, yeah
- start = (unsigned char *)-1;
- }
- else
- {
- start = s_chan[ch].pLoop;
- }
- }
- // store values for next cycle
- s_chan[ch].pCurr = start;
- s_chan[ch].s_1 = s_1;
- s_chan[ch].s_2 = s_2;
- // special return for
- // "spu irq - wait for cpu action"
- if(bIRQReturn)
- {
- bIRQReturn = 0;
- lastch = ch;
- lastns = ns;
- return 0;
- }
- GOON:
- ;
- }
- // get sample data
- fa = s_chan[ch].SB[s_chan[ch].iSBPos++];
- // muted?
- if((spuCtrl & 0x4000) == 0)
- fa = 0;
- // else adjust
- else
- {
- if(fa > 32767L)
- fa = 32767L;
- if(fa < -32767L)
- fa = -32767L;
- }
- // gauss/cubic interpolation
- if(iUseInterpolation >= 2)
- {
- gpos = s_chan[ch].SB[28];
- gval0 = fa;
- gpos = (gpos + 1) & 3;
- s_chan[ch].SB[28] = gpos;
- }
- // simple interpolation
- else if(iUseInterpolation == 1)
- {
- s_chan[ch].SB[28] = 0;
- // helpers for simple linear interpolation:
- // delay real val for two slots, and calc
- // the two deltas, for a
- // 'look at the future behaviour'
- s_chan[ch].SB[29] = s_chan[ch].SB[30];
- s_chan[ch].SB[30] = s_chan[ch].SB[31];
- s_chan[ch].SB[31] = fa;
- // flag: calc new interpolation
- s_chan[ch].SB[32] = 1;
- }
- // no interpolation
- else
- s_chan[ch].SB[29] = fa;
- s_chan[ch].spos -= 0x10000L;
- }
- // noise handler... just produces some noise data
- // surely wrong...
- // and no noise frequency (spuCtrl & 0x3f00) will be used...
- // and sometimes the noise will be
- // used as fmod modulation... pfff
- if(s_chan[ch].bNoise)
- {
- if((dwNoiseVal <<= 1) & 0x80000000L)
- {
- dwNoiseVal ^= 0x0040001L;
- fa = ((dwNoiseVal >> 2) & 0x7fff);
- fa = -fa;
- }
- else
- fa = (dwNoiseVal >> 2) & 0x7fff;
- // mmm... depending on the noise freq we allow
- // bigger/smaller changes to the previous val
- fa = s_chan[ch].iOldNoise +
- ((fa - s_chan[ch].iOldNoise) /
- ((0x001f - ((spuCtrl & 0x3f00) >> 9)) + 1));
- if(fa > 32767L)
- fa = 32767L;
- if(fa < -32767L)
- fa = -32767L;
- s_chan[ch].iOldNoise = fa;
- // no gauss/cubic interpolation?
- if(iUseInterpolation < 2)
- // store noise val in "current sample slot"
- s_chan[ch].SB[29] = fa;
- }
- // NO NOISE (NORMAL SAMPLE DATA) HERE
- else
- {
- // cubic interpolation
- if(iUseInterpolation == 3)
- {
- long xd;
- xd = ((s_chan[ch].spos) >> 1) + 1;
- gpos = s_chan[ch].SB[28];
- fa = gval(3) - 3 * gval(2) + 3 * gval(1) - gval0;
- fa *= (xd - (2 << 15)) / 6;
- fa >>= 15;
- fa += gval(2) - gval(1) - gval(1) + gval0;
- fa *= (xd - (1 << 15)) >> 1;
- fa >>= 15;
- fa += gval(1) - gval0;
- fa *= xd;
- fa >>= 15;
- fa = fa + gval0;
- }
- // gauss interpolation
- else if(iUseInterpolation == 2)
- {
- int vl, vr;
- vl = (s_chan[ch].spos >> 6) & ~3;
- gpos = s_chan[ch].SB[28];
- vr = (gauss[vl] * gval0) & ~2047;
- vr += (gauss[vl + 1] * gval(1)) & ~2047;
- vr += (gauss[vl + 2] * gval(2)) & ~2047;
- vr += (gauss[vl + 3] * gval(3)) & ~2047;
- fa = vr >> 11;
- }
- // simple interpolation
- else if(iUseInterpolation == 1)
- {
- // upsampling?
- if(s_chan[ch].sinc < 0x10000L)
- InterpolateUp(ch);
- else
- InterpolateDown(ch);
- fa = s_chan[ch].SB[29];
- }
- else
- // no interpolation
- fa = s_chan[ch].SB[29];
- }
- // add adsr
- s_chan[ch].sval = (MixADSR(ch) * fa) / 1023;
- // fmod freq channel
- if(s_chan[ch].bFMod == 2)
- {
- int NP = s_chan[ch+1].iRawPitch;
- NP = ((32768L + s_chan[ch].sval) * NP) / 32768L;
- if(NP > 0x3fff)
- NP = 0x3fff;
- if(NP < 0x1)
- NP = 0x1;
- // mmmm... if I do this, all is screwed
- // s_chan[ch+1].iRawPitch=NP;
- // calc frequency
- NP = (44100L * NP) / (4096L);
- s_chan[ch + 1].iActFreq = NP;
- s_chan[ch + 1].iUsedFreq = NP;
- s_chan[ch + 1].sinc = (((NP / 10) << 16) / 4410);
- if(!s_chan[ch + 1].sinc)
- s_chan[ch + 1].sinc = 1;
- // freq change in simple interpolation mode
- if(iUseInterpolation == 1)
- s_chan[ch + 1].SB[32] = 1;
- // mmmm... set up freq decoding positions?
- // s_chan[ch+1].iSBPos=28;
- // s_chan[ch+1].spos=0x10000L;
- }
- else
- {
- // ok, left/right sound volume
- // (psx volume goes from 0 ... 0x3fff)
- // debug mute
- if(s_chan[ch].iMute)
- s_chan[ch].sval = 0;
- else
- {
- SSumL[ns] += (s_chan[ch].sval *
- s_chan[ch].iLeftVolume) / 0x4000L;
- SSumR[ns] += (s_chan[ch].sval *
- s_chan[ch].iRightVolume) / 0x4000L;
- }
- // now let us store sound data for reverb
- if(s_chan[ch].bRVBActive)
- StoreREVERB(ch, ns);
- }
- // ok, go on until 1 ms data
- // of this channel is collected
- ns++;
- s_chan[ch].spos += s_chan[ch].sinc;
- } // while(ns < NSSIZE)
- ENDX:
- ;
- } // for(ch = 0; ch < MAXCHAN; ch++)
- }
- // here we have another 1 ms of sound data
- // mix XA infos (if any)
- if(XAPlay != XAFeed || XARepeat)
- MixXA();
- // mix all channels (including reverb) into one buffer
- /*
- // no stereo?
- if(iDisStereo)
- {
- int dl, dr;
- for(ns = 0; ns < NSSIZE; ns++)
- {
- SSumL[ns] += MixREVERBLeft(ns);
- dl = SSumL[ns] / voldiv;
- SSumL[ns] = 0;
- if(dl < -32767)
- dl = -32767;
- if(dl > 32767)
- dl = 32767;
- SSumR[ns] += MixREVERBRight();
- dr = SSumR[ns] / voldiv;
- SSumR[ns] = 0;
- if(dr < -32767)
- dr = -32767;
- if(dr > 32767)
- dr = 32767;
- *pS++ = (dl + dr) / 2;
- }
- }
- // stereo
- else
- */
- for(ns = 0; ns < NSSIZE; ns++)
- {
- SSumL[ns] += MixREVERBLeft(ns);
- d = SSumL[ns] / voldiv;
- SSumL[ns] = 0;
- if(d < -32767)
- d = -32767;
- if(d > 32767)
- d = 32767;
- *pS++ = d;
- SSumR[ns] += MixREVERBRight();
- d = SSumR[ns] / voldiv;
- SSumR[ns] = 0;
- if(d < -32767)
- d = -32767;
- if(d > 32767)
- d = 32767;
- *pS++ = d;
- }
- InitREVERB();
- // feed the sound
- // wanna have around 1/60 sec (16.666 ms) updates
- //temp fix: lowered for low latency alsa configs
- if(iCycle++ > 8)
- {
- SBE->FeedStreamData((u8 *)pSpuBuffer,
- ((unsigned char *)pS) -
- ((unsigned char *)pSpuBuffer));
- pS = (short *)pSpuBuffer;
- iCycle = 0;
- }
- }
- // end of big main loop...
- bThreadEnded = 1;
- return 0;
- }
- void SPUasync(unsigned long cycle)
- {
- // clear the watchdog
- iWatchDog = 0;
- // special mode, only used in Linux by this spu
- // (or if you enable the experimental Windows mode)
- if(iUseTimer == 2)
- {
- // no init, no call
- if(!bSpuInit)
- return;
- // linux high-compat mode
- MAINThread(0);
- }
- }
- void SPUupdate(void)
- {
- SPUasync(0);
- }
- void SPUplayADPCMchannel(xa_decode_t *xap)
- {
- if(!iUseXA)
- return;
- if(!xap)
- return;
- if(!xap->freq)
- return;
- FeedXA(xap);
- }
- long SPUinit(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUinit()" << std::endl;
- #endif
- spuMemC = (unsigned char *)spuMem;
- memset((void *)s_chan, 0, MAXCHAN * sizeof(SPUCHAN));
- memset((void *)&rvb, 0, sizeof(REVERBInfo));
- InitADSR();
- return 0;
- }
- void SetupTimer(void)
- {
- // init some mixing buffers
- memset(SSumR, 0, NSSIZE * sizeof(int));
- memset(SSumL, 0, NSSIZE * sizeof(int));
- // setup soundbuffer pointer
- pS = (short *)pSpuBuffer;
- // init thread vars
- bEndThread = 0;
- bThreadEnded = 0;
- // flag: we are inited
- bSpuInit = 1;
- }
- void RemoveTimer(void)
- {
- // raise flag to end thread
- bEndThread = 1;
- if(!iUseTimer)
- {
- int i = 0;
- // wait until thread has ended
- while(!bThreadEnded && i < 2000)
- {
- #ifndef _MSC_VER
- usleep(10);
- #else
- Sleep(10);
- #endif
- // SDL_Delay(1000L);
- i++;
- }
- }
- // no more spu is running
- bThreadEnded = 0;
- bSpuInit = 0;
- }
- void SetupStreams(void)
- {
- int i;
- // alloc mixing buffer
- pSpuBuffer = (unsigned char *)malloc(32768);
- if(iUseReverb == 1)
- i = 88200 * 2;
- else
- i = NSSIZE * 2;
- // alloc reverb buffer
- sRVBStart = (int *)malloc(i * 4);
- memset(sRVBStart, 0, i * 4);
- sRVBEnd = sRVBStart + i;
- sRVBPlay = sRVBStart;
- // alloc xa buffer
- XAStart = (u32 *)malloc(44100 * 4);
- XAPlay = XAStart;
- XAFeed = XAStart;
- XAEnd = XAStart + 44100;
- for(i = 0; i < MAXCHAN; i++)
- {
- // we don't use mutex sync... not needed, would only
- // slow us down:
- // init sustain
- s_chan[i].ADSRX.SustainLevel = 1024;
- s_chan[i].iMute = 0;
- s_chan[i].iIrqDone = 0;
- s_chan[i].pLoop = spuMemC;
- s_chan[i].pStart = spuMemC;
- s_chan[i].pCurr = spuMemC;
- }
- }
- void RemoveStreams(void)
- {
- // free mixing buffer
- free(pSpuBuffer);
- pSpuBuffer = NULL;
- // free reverb buffer
- free(sRVBStart);
- sRVBStart = 0;
- // free xa buffer
- free(XAStart);
- XAStart = 0;
- }
- long SPUopen(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUopen()" << std::endl;
- #endif
- // security for some stupid main emus
- if(bSPUIsOpen)
- return 0;
- iUseXA = 1;
- iVolume = 3;
- iReverbOff = -1;
- spuIrq = 0;
- spuAddr = 0xffffffff;
- bEndThread = 0;
- bThreadEnded = 0;
- spuMemC = (unsigned char *)spuMem;
- memset((void *)s_chan, 0, (MAXCHAN + 1) * sizeof(SPUCHAN));
- pSpuIrq = 0;
- iSPUIRQWait = 1;
- SBE = new SoundBackendSDL();
- // prepare streaming
- SetupStreams();
- // timer for feeding data
- SetupTimer();
- bSPUIsOpen = 1;
- return PSE_SPU_ERR_SUCCESS;
- }
- void SPUsetConfigFile(char * pCfg)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUsetConfigFile()" << std::endl;
- #endif
- // pConfigFile = pCfg;
- }
- long SPUclose(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUclose()" << std::endl;
- #endif
- // security
- if(!bSPUIsOpen)
- return 0;
- bSPUIsOpen = 0;
- RemoveTimer();
- if(SBE != NULL)
- delete SBE;
- RemoveStreams();
- return 0;
- }
- long SPUshutdown(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUshutdown()" << std::endl;
- #endif
- return 0;
- }
- long SPUtest(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUtest()" << std::endl;
- #endif
- return 0;
- }
- long SPUconfigure(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUconfigure()" << std::endl;
- #endif
- //G StartCfgTool("CFG");
- return 0;
- }
- void SPUabout(void)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUabout()" << std::endl;
- #endif
- //G StartCfgTool("ABOUT");
- }
- void SPUregisterCallback(void (*callback)(void))
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUregisterCallback()" << std::endl;
- #endif
- irqCallback = callback;
- }
- void SPUregisterCDDAVolume(void (*CDDAVcallback)(unsigned short,unsigned short))
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUregisterCDDAVolume()" << std::endl;
- #endif
- cddavCallback = CDDAVcallback;
- }
- unsigned short SPUgetOne(unsigned long val)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUgetOne()" << std::endl;
- #endif
- if(spuAddr != 0xffffffff)
- {
- return SPUreadDMA();
- }
- if(val >= 512 * 1024)
- val = 512 * 1024 - 1;
- return spuMem[val >> 1];
- }
- void SPUputOne(unsigned long val, unsigned short data)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUputOne()" << std::endl;
- #endif
- if(spuAddr != 0xffffffff)
- {
- SPUwriteDMA(data);
- return;
- }
- if(val >= 512 * 1024)
- val = 512 * 1024 - 1;
- spuMem[val >> 1] = data;
- }
- void SPUplaySample(unsigned char ch)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUplaySample()" << std::endl;
- #endif
- }
- void SPUsetAddr(unsigned char ch, unsigned short waddr)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUsetAddr()" << std::endl;
- #endif
- s_chan[ch].pStart = spuMemC + ((unsigned long)waddr << 3);
- }
- void SPUsetPitch(unsigned char ch, unsigned short pitch)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUsetPitch()" << std::endl;
- #endif
- SetPitch(ch, pitch);
- }
- void SPUsetVolumeL(unsigned char ch, short vol)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUsetVolumeL()" << std::endl;
- #endif
- SetVolumeR(ch, vol);
- }
- void SPUsetVolumeR(unsigned char ch, short vol)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUsetVolumeR()" << std::endl;
- #endif
- SetVolumeL(ch, vol);
- }
- void SPUstartChannels1(unsigned short channels)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUstartChannels1()" << std::endl;
- #endif
- SoundOn(0, 16, channels);
- }
- void SPUstartChannels2(unsigned short channels)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUstartChannels2()" << std::endl;
- #endif
- SoundOn(16, 24, channels);
- }
- void SPUstopChannels1(unsigned short channels)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUstopChannels1()" << std::endl;
- #endif
- SoundOff(0, 16, channels);
- }
- void SPUstopChannels2(unsigned short channels)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUstopChannels2()" << std::endl;
- #endif
- SoundOff(16, 24, channels);
- }
- void SPUplaySector(unsigned long mode, unsigned char *p)
- {
- #ifdef DEBUG_OUTPUT
- std::cout << "*** SPUplaySector()\n" << std::endl;
- #endif
- // no XA
- if(!iUseXA)
- return;
- }
- u32 GGetTime()
- {
- #ifndef _MSC_VER
- // well, maybe there are better ways
- // to do that, but at least it works
- struct timeval tv;
- gettimeofday(&tv, 0);
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
- #else
- return ::GetTickCount(); // TODO FIX ME, probably wrong
- #endif
- }
|