1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774 |
- /*
- Copyright (C) 1994-1995 Apogee Software, Ltd.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /**********************************************************************
- file: GUSWAVE.C
- author: James R. Dose
- date: March 23, 1994
- Digitized sound playback routines for the Gravis Ultrasound.
- (c) Copyright 1994 James R. Dose. All Rights Reserved.
- **********************************************************************/
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <stdio.h>
- #include <io.h>
- #include <string.h>
- #include "debugio.h"
- #include "interrup.h"
- #include "ll_man.h"
- #include "pitch.h"
- #include "user.h"
- #include "multivoc.h"
- #include "_guswave.h"
- #include "newgf1.h"
- #include "gusmidi.h"
- #include "guswave.h"
- #define ATR_INDEX 0x3c0
- #define STATUS_REGISTER_1 0x3da
- #define SetBorderColor(color) \
- { \
- inp (STATUS_REGISTER_1); \
- outp (ATR_INDEX,0x31); \
- outp (ATR_INDEX,color); \
- }
- static const int GUSWAVE_PanTable[ 32 ] =
- {
- 8, 9, 10, 11, 11, 12, 13, 14,
- 15, 14, 13, 12, 11, 10, 9, 8,
- 7, 6, 5, 4, 4, 3, 2, 1,
- 0, 1, 2, 3, 4, 5, 6, 7
- };
- static voicelist VoiceList;
- static voicelist VoicePool;
- static voicestatus VoiceStatus[ MAX_VOICES ];
- //static
- VoiceNode GUSWAVE_Voices[ VOICES ];
- static int GUSWAVE_VoiceHandle = GUSWAVE_MinVoiceHandle;
- static int GUSWAVE_MaxVoices = VOICES;
- //static
- int GUSWAVE_Installed = FALSE;
- static void ( *GUSWAVE_CallBackFunc )( unsigned long ) = NULL;
- // current volume for dig audio - from 0 to 4095
- static int GUSWAVE_Volume = MAX_VOLUME;
- static int GUSWAVE_SwapLeftRight = FALSE;
- static int GUS_Debug = FALSE;
- extern int GUSMIDI_Installed;
- int GUSWAVE_ErrorCode = GUSWAVE_Ok;
- #define GUSWAVE_SetErrorCode( status ) \
- GUSWAVE_ErrorCode = ( status );
- /*---------------------------------------------------------------------
- Function: GUSWAVE_ErrorString
- Returns a pointer to the error message associated with an error
- number. A -1 returns a pointer the current error.
- ---------------------------------------------------------------------*/
- char *GUSWAVE_ErrorString
- (
- int ErrorNumber
- )
- {
- char *ErrorString;
- switch( ErrorNumber )
- {
- case GUSWAVE_Warning :
- case GUSWAVE_Error :
- ErrorString = GUSWAVE_ErrorString( GUSWAVE_ErrorCode );
- break;
- case GUSWAVE_Ok :
- ErrorString = "GUSWAVE ok.";
- break;
- case GUSWAVE_GUSError :
- ErrorString = GUS_ErrorString( GUS_Error );
- break;
- case GUSWAVE_NotInstalled :
- ErrorString = "GUSWAVE not installed.";
- break;
- case GUSWAVE_NoVoices :
- ErrorString = "No free voices available to GUSWAVE.";
- break;
- case GUSWAVE_UltraNoMem :
- ErrorString = "Not enough Ultrasound memory available for GUSWAVE.";
- break;
- case GUSWAVE_UltraNoMemMIDI :
- ErrorString = "Not enough Ultrasound memory available for GUSWAVE. "
- "Try initializing Sound FX before Music.";
- break;
- case GUSWAVE_VoiceNotFound :
- ErrorString = "No voice with matching handle found.";
- break;
- case GUSWAVE_InvalidVOCFile :
- ErrorString = "Invalid VOC file passed in to GUSWAVE.";
- break;
- case GUSWAVE_InvalidWAVFile :
- ErrorString = "Invalid WAV file passed in to GUSWAVE.";
- break;
- default :
- ErrorString = "Unknown GUSWAVE error code.";
- break;
- }
- return( ErrorString );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_CallBack
- GF1 callback service routine.
- ---------------------------------------------------------------------*/
- char GUS_Silence8[ 1024 ] = //256 ] =
- {
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
- };
- //unsigned short GUS_Silence16[ 128 ] =
- unsigned short GUS_Silence16[ 512 ] =
- {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- static int LOADDS GUSWAVE_CallBack
- (
- int reason,
- int voice,
- unsigned char **buf,
- unsigned long *size
- )
- {
- VoiceNode *Voice;
- playbackstatus status;
- // this function is called from an interrupt
- // remember not to make any DOS or BIOS calls from here
- // also don't call any C library functions unless you are sure that
- // they are reentrant
- // restore our DS register
- if ( VoiceStatus[ voice ].playing == FALSE )
- {
- return( DIG_DONE );
- }
- if ( reason == DIG_MORE_DATA )
- {
- // SetBorderColor(16);
- Voice = VoiceStatus[ voice ].Voice;
- if ( ( Voice != NULL ) && ( Voice->Playing ) )
- /*
- {
- *buf = ( unsigned char * )GUS_Silence16;
- *size = 1024;
- SetBorderColor(0);
- return( DIG_MORE_DATA );
- }
- */
- {
- status = Voice->GetSound( Voice );
- if ( status != SoundDone )
- {
- if ( ( Voice->sound == NULL ) || ( status == NoMoreData ) )
- {
- if ( Voice->bits == 8 )
- {
- *buf = GUS_Silence8;
- }
- else
- {
- *buf = ( unsigned char * )GUS_Silence16;
- }
- *size = 256;
- }
- else
- {
- *buf = Voice->sound;
- *size = Voice->length;
- }
- return( DIG_MORE_DATA );
- }
- }
- // SetBorderColor(16);
- return( DIG_DONE );
- }
- if ( reason == DIG_DONE )
- {
- Voice = VoiceStatus[ voice ].Voice;
- VoiceStatus[ voice ].playing = FALSE;
- if ( Voice != NULL )
- {
- Voice->Active = FALSE;
- Voice->Playing = FALSE;
- // I'm commenting this out because a -1 could cause a crash if it
- // is sent to the GF1 code. This shouldn't be necessary since
- // Active should be false when GF1voice is -1, but this is just
- // a precaution. Adjust the pan on the wrong voice is a lot
- // more pleasant than a crash!
- // Voice->GF1voice = -1;
- LL_Remove( VoiceNode, &VoiceList, Voice );
- LL_AddToTail( VoiceNode, &VoicePool, Voice );
- }
- if ( GUSWAVE_CallBackFunc )
- {
- GUSWAVE_CallBackFunc( Voice->callbackval );
- }
- }
- return( DIG_DONE );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_DebugCallBack
- GF1 callback service routine with debugging info.
- ---------------------------------------------------------------------*/
- static int LOADDS GUSWAVE_DebugCallBack
- (
- int reason,
- int voice,
- unsigned char **buf,
- unsigned long *size
- )
- {
- VoiceNode *Voice;
- // this function is called from an interrupt
- // remember not to make any DOS or BIOS calls from here
- // also don't call any C library functions unless you are sure that
- // they are reentrant
- // restore our DS register
- if ( VoiceStatus[ voice ].playing == FALSE )
- {
- // DB_printf( "GUS Voice %d not playing.\n", voice );
- DB_printf( "GUS Voice " );
- DB_PrintNum( voice );
- DB_printf( " not playing.\n" );
- return( DIG_DONE );
- }
- if ( reason == DIG_MORE_DATA )
- {
- Voice = VoiceStatus[ voice ].Voice;
- // DB_printf( "Voice %d : More data -- ", Voice );
- DB_printf( "Voice " );
- DB_PrintNum( voice );
- DB_printf( " : More data -- " );
- if ( Voice != NULL )
- {
- if ( Voice->Playing )
- {
- GUSWAVE_GetNextVOCBlock( Voice );
- if ( Voice->Playing )
- {
- // DB_printf( "More data -- size = %u blocklength = %u\n",
- // Voice->length, Voice->BlockLength );
- DB_printf( "More data -- size = " );
- DB_PrintNum( Voice->length );
- DB_printf( " blocklength = " );
- DB_PrintNum( Voice->BlockLength );
- DB_printf( "\n" );
- *buf = Voice->sound;
- *size = Voice->length;
- return( DIG_MORE_DATA );
- }
- else
- {
- DB_printf( "Voice done.\n" );
- }
- }
- else
- {
- DB_printf( "Voice not active.\n" );
- }
- }
- else
- {
- DB_printf( " NULL Voice\n" );
- }
- return( DIG_DONE );
- }
- if ( reason == DIG_DONE )
- {
- VoiceStatus[ voice ].playing = FALSE;
- Voice = VoiceStatus[ voice ].Voice;
- // DB_printf( "Voice %d : Done -- ", Voice );
- DB_printf( "Voice " );
- DB_PrintNum( voice );
- DB_printf( " : Done -- " );
- if ( Voice != NULL )
- {
- DB_printf( "Ok\n" );
- Voice->Active = FALSE;
- Voice->Playing = FALSE;
- // I'm commenting this out because a -1 could cause a crash if it
- // is sent to the GF1 code. This shouldn't be necessary since
- // Active should be false when GF1voice is -1, but this is just
- // a precaution. Adjust the pan on the wrong voice is a lot
- // more pleasant than a crash!
- // Voice->GF1voice = -1;
- LL_Remove( VoiceNode, &VoiceList, Voice );
- LL_AddToTail( VoiceNode, &VoicePool, Voice );
- }
- else
- {
- DB_printf( "Null voice\n" );
- }
- if ( GUSWAVE_CallBackFunc )
- {
- GUSWAVE_CallBackFunc( Voice->callbackval );
- }
- }
- return( DIG_DONE );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetVoice
- Locates the voice with the specified handle.
- ---------------------------------------------------------------------*/
- static VoiceNode *GUSWAVE_GetVoice
- (
- int handle
- )
- {
- VoiceNode *voice;
- unsigned flags;
- flags = DisableInterrupts();
- voice = VoiceList.start;
- while( voice != NULL )
- {
- if ( handle == voice->handle )
- {
- break;
- }
- voice = voice->next;
- }
- RestoreInterrupts( flags );
- if ( voice == NULL )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
- }
- return( voice );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_VoicePlaying
- Checks if the voice associated with the specified handle is
- playing.
- ---------------------------------------------------------------------*/
- int GUSWAVE_VoicePlaying
- (
- int handle
- )
- {
- VoiceNode *voice;
- voice = GUSWAVE_GetVoice( handle );
- if ( voice != NULL )
- {
- return( voice->Active );
- }
- return( FALSE );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_VoicesPlaying
- Determines the number of currently active voices.
- ---------------------------------------------------------------------*/
- int GUSWAVE_VoicesPlaying
- (
- void
- )
- {
- int index;
- int NumVoices = 0;
- unsigned flags;
- flags = DisableInterrupts();
- for( index = 0; index < GUSWAVE_MaxVoices; index++ )
- {
- if ( GUSWAVE_Voices[ index ].Active )
- {
- NumVoices++;
- }
- }
- RestoreInterrupts( flags );
- if ( GUS_Debug )
- {
- DB_printf( "Number of voices = %d.\n", NumVoices );
- }
- return( NumVoices );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_Kill
- Stops output of the voice associated with the specified handle.
- ---------------------------------------------------------------------*/
- int GUSWAVE_Kill
- (
- int handle
- )
- {
- VoiceNode *voice;
- unsigned flags;
- flags = DisableInterrupts();
- voice = GUSWAVE_GetVoice( handle );
- if ( voice == NULL )
- {
- RestoreInterrupts( flags );
- GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
- if ( GUS_Debug )
- {
- DB_printf( "Could not find voice to kill.\n" );
- }
- return( GUSWAVE_Warning );
- }
- RestoreInterrupts( flags );
- if ( !GUS_Debug )
- {
- if ( voice->Active )
- {
- gf1_stop_digital( voice->GF1voice );
- }
- }
- else
- {
- DB_printf( "Kill - GUS Voice %d ", voice->GF1voice );
- if ( voice->Active )
- {
- DB_printf( "active\n" );
- gf1_stop_digital( voice->GF1voice );
- }
- else
- {
- DB_printf( "inactive\n" );
- }
- }
- // RestoreInterrupts( flags );
- return( GUSWAVE_Ok );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_KillAllVoices
- Stops output of all currently active voices.
- ---------------------------------------------------------------------*/
- int GUSWAVE_KillAllVoices
- (
- void
- )
- {
- int i;
- unsigned flags;
- if ( !GUSWAVE_Installed )
- {
- return( GUSWAVE_Ok );
- }
- if ( GUS_Debug )
- {
- DB_printf( "Kill All Voices\n" );
- }
- flags = DisableInterrupts();
- // Remove all the voices from the list
- for( i = 0; i < GUSWAVE_MaxVoices; i++ )
- {
- if ( GUSWAVE_Voices[ i ].Active )
- {
- // GUSWAVE_Kill( GUSWAVE_Voices[ i ].handle );
- gf1_stop_digital( GUSWAVE_Voices[ i ].GF1voice );
- }
- }
- for( i = 0; i < MAX_VOICES; i++ )
- {
- VoiceStatus[ i ].playing = FALSE;
- VoiceStatus[ i ].Voice = NULL;
- }
- VoicePool.start = NULL;
- VoicePool.end = NULL;
- VoiceList.start = NULL;
- VoiceList.end = NULL;
- for( i = 0; i < GUSWAVE_MaxVoices; i++ )
- {
- GUSWAVE_Voices[ i ].Active = FALSE;
- if ( GUSWAVE_Voices[ i ].mem != NULL )
- {
- LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
- }
- }
- RestoreInterrupts( flags );
- return( GUSWAVE_Ok );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_SetPitch
- Sets the pitch for the voice associated with the specified handle.
- ---------------------------------------------------------------------*/
- int GUSWAVE_SetPitch
- (
- int handle,
- int pitchoffset
- )
- {
- VoiceNode *voice;
- unsigned flags;
- flags = DisableInterrupts();
- voice = GUSWAVE_GetVoice( handle );
- if ( voice == NULL )
- {
- RestoreInterrupts( flags );
- GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
- return( GUSWAVE_Warning );
- }
- if ( voice->Active )
- {
- voice->PitchScale = PITCH_GetScale( pitchoffset );
- voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
- gf1_dig_set_freq( voice->GF1voice, voice->RateScale );
- }
- RestoreInterrupts( flags );
- return( GUSWAVE_Ok );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_SetPan3D
- Sets the pan position of the voice with the specified handle.
- ---------------------------------------------------------------------*/
- int GUSWAVE_SetPan3D
- (
- int handle,
- int angle,
- int distance
- )
- {
- VoiceNode *voice;
- int pan;
- unsigned flags;
- flags = DisableInterrupts();
- voice = GUSWAVE_GetVoice( handle );
- if ( voice == NULL )
- {
- RestoreInterrupts( flags );
- GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
- return( GUSWAVE_Warning );
- }
- if ( voice->Active )
- {
- angle &= 31;
- pan = GUSWAVE_PanTable[ angle ];
- if ( GUSWAVE_SwapLeftRight )
- {
- pan = 15 - pan;
- }
- distance = max( 0, distance );
- distance = min( 255, distance );
- voice->Volume = 255 - distance;
- voice->Pan = pan;
- gf1_dig_set_pan( voice->GF1voice, pan );
- gf1_dig_set_vol( voice->GF1voice, GUSWAVE_Volume - distance * 4 );
- }
- RestoreInterrupts( flags );
- return( GUSWAVE_Ok );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_SetVolume
- Sets the total volume of the digitized sounds.
- ---------------------------------------------------------------------*/
- void GUSWAVE_SetVolume
- (
- int volume
- )
- {
- int i;
- volume = max( 0, volume );
- volume = min( 255, volume );
- GUSWAVE_Volume = MAX_VOLUME - ( 255 - volume ) * 4;
- for( i = 0; i < GUSWAVE_MaxVoices; i++ )
- {
- if ( GUSWAVE_Voices[ i ].Active )
- {
- gf1_dig_set_vol( GUSWAVE_Voices[ i ].GF1voice,
- GUSWAVE_Volume - ( 255 - GUSWAVE_Voices[ i ].Volume ) * 4 );
- }
- }
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetVolume
- Returns the total volume of the digitized sounds.
- ---------------------------------------------------------------------*/
- int GUSWAVE_GetVolume
- (
- void
- )
- {
- return( 255 - ( ( MAX_VOLUME - GUSWAVE_Volume ) / 4 ) );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_AllocVoice
- Retrieve an inactive or lower priority voice for output.
- ---------------------------------------------------------------------*/
- static VoiceNode *GUSWAVE_AllocVoice
- (
- int priority
- )
- {
- VoiceNode *voice;
- VoiceNode *node;
- unsigned flags;
- // If we don't have any free voices, check if we have a higher
- // priority than one that is playing.
- if ( GUSWAVE_VoicesPlaying() >= GUSWAVE_MaxVoices )
- {
- flags = DisableInterrupts();
- node = VoiceList.start;
- voice = node;
- while( node != NULL )
- {
- if ( node->priority < voice->priority )
- {
- voice = node;
- }
- node = node->next;
- }
- RestoreInterrupts( flags );
- if ( priority >= voice->priority )
- {
- GUSWAVE_Kill( voice->handle );
- }
- }
- // Check if any voices are in the voice pool
- flags = DisableInterrupts();
- voice = VoicePool.start;
- if ( voice != NULL )
- {
- LL_Remove( VoiceNode, &VoicePool, voice );
- }
- RestoreInterrupts( flags );
- if ( voice != NULL )
- {
- do
- {
- GUSWAVE_VoiceHandle++;
- if ( GUSWAVE_VoiceHandle < GUSWAVE_MinVoiceHandle )
- {
- GUSWAVE_VoiceHandle = GUSWAVE_MinVoiceHandle;
- }
- }
- while( GUSWAVE_VoicePlaying( GUSWAVE_VoiceHandle ) );
- voice->handle = GUSWAVE_VoiceHandle;
- }
- return( voice );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_VoiceAvailable
- Checks if a voice can be play at the specified priority.
- ---------------------------------------------------------------------*/
- int GUSWAVE_VoiceAvailable
- (
- int priority
- )
- {
- VoiceNode *voice;
- VoiceNode *node;
- unsigned flags;
- if ( GUSWAVE_VoicesPlaying() < GUSWAVE_MaxVoices )
- {
- return( TRUE );
- }
- flags = DisableInterrupts();
- node = VoiceList.start;
- voice = node;
- while( node != NULL )
- {
- if ( node->priority < voice->priority )
- {
- voice = node;
- }
- node = node->next;
- }
- RestoreInterrupts( flags );
- if ( priority >= voice->priority )
- {
- return( TRUE );
- }
- return( FALSE );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetNextVOCBlock
- Interperate the information of a VOC format sound file.
- ---------------------------------------------------------------------*/
- playbackstatus GUSWAVE_GetNextVOCBlock
- (
- VoiceNode *voice
- )
- {
- unsigned char *ptr;
- int blocktype;
- int lastblocktype;
- unsigned long blocklength;
- unsigned long samplespeed;
- unsigned int tc;
- int packtype;
- int voicemode;
- int done;
- unsigned BitsPerSample;
- unsigned Channels;
- unsigned Format;
- if ( voice->BlockLength > 0 )
- {
- voice->sound += MAX_BLOCK_LENGTH;
- voice->length = min( voice->BlockLength, MAX_BLOCK_LENGTH );
- voice->BlockLength -= voice->length;
- return( KeepPlaying );
- }
- ptr = ( unsigned char * )voice->NextBlock;
- voice->Playing = TRUE;
- voicemode = 0;
- lastblocktype = 0;
- packtype = 0;
- done = FALSE;
- while( !done )
- {
- // Stop playing if we get a NULL pointer
- if ( ptr == NULL )
- {
- voice->Playing = FALSE;
- done = TRUE;
- break;
- }
- blocktype = ( int )*ptr;
- blocklength = ( *( unsigned long * )( ptr + 1 ) ) & 0x00ffffff;
- ptr += 4;
- switch( blocktype )
- {
- case 0 :
- // End of data
- voice->Playing = FALSE;
- done = TRUE;
- break;
- case 1 :
- // Sound data block
- voice->bits = 8;
- if ( lastblocktype != 8 )
- {
- tc = ( unsigned int )*ptr << 8;
- packtype = *( ptr + 1 );
- }
- ptr += 2;
- blocklength -= 2;
- samplespeed = 256000000L / ( 65536 - tc );
- // Skip packed or stereo data
- if ( ( packtype != 0 ) || ( voicemode != 0 ) )
- {
- ptr += blocklength;
- }
- else
- {
- done = TRUE;
- }
- voicemode = 0;
- break;
- case 2 :
- // Sound continuation block
- samplespeed = voice->SamplingRate;
- done = TRUE;
- break;
- case 3 :
- // Silence
- // Not implimented.
- ptr += blocklength;
- break;
- case 4 :
- // Marker
- // Not implimented.
- ptr += blocklength;
- break;
- case 5 :
- // ASCII string
- // Not implimented.
- ptr += blocklength;
- break;
- case 6 :
- // Repeat begin
- voice->LoopCount = *( unsigned short * )ptr;
- ptr += blocklength;
- voice->LoopStart = ptr;
- break;
- case 7 :
- // Repeat end
- ptr += blocklength;
- if ( lastblocktype == 6 )
- {
- voice->LoopCount = 0;
- }
- else
- {
- if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
- {
- ptr = voice->LoopStart;
- if ( voice->LoopCount < 0xffff )
- {
- voice->LoopCount--;
- if ( voice->LoopCount == 0 )
- {
- voice->LoopStart = NULL;
- }
- }
- }
- }
- break;
- case 8 :
- // Extended block
- voice->bits = 8;
- tc = *( unsigned short * )ptr;
- packtype = *( ptr + 2 );
- voicemode = *( ptr + 3 );
- ptr += blocklength;
- break;
- case 9 :
- // New sound data block
- samplespeed = *( unsigned long * )ptr;
- BitsPerSample = ( unsigned )*( ptr + 4 );
- Channels = ( unsigned )*( ptr + 5 );
- Format = ( unsigned )*( unsigned short * )( ptr + 6 );
- if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
- ( Format == VOC_8BIT ) )
- {
- ptr += 12;
- blocklength -= 12;
- voice->bits = 8;
- done = TRUE;
- }
- else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
- ( Format == VOC_16BIT ) )
- {
- ptr += 12;
- blocklength -= 12;
- voice->bits = 16;
- done = TRUE;
- }
- else
- {
- ptr += blocklength;
- }
- break;
- default :
- // Unknown data. Probably not a VOC file.
- voice->Playing = FALSE;
- done = TRUE;
- break;
- }
- lastblocktype = blocktype;
- }
- if ( voice->Playing )
- {
- voice->NextBlock = ptr + blocklength;
- voice->sound = ptr;
- voice->SamplingRate = samplespeed;
- voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
- voice->length = min( blocklength, MAX_BLOCK_LENGTH );
- voice->BlockLength = blocklength - voice->length;
- return( KeepPlaying );
- }
- return( SoundDone );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetNextWAVBlock
- Controls playback of demand fed data.
- ---------------------------------------------------------------------*/
- playbackstatus GUSWAVE_GetNextWAVBlock
- (
- VoiceNode *voice
- )
- {
- if ( voice->BlockLength <= 0 )
- {
- if ( voice->LoopStart == NULL )
- {
- voice->Playing = FALSE;
- return( SoundDone );
- }
- voice->BlockLength = voice->LoopSize;
- voice->NextBlock = voice->LoopStart;
- voice->length = 0;
- }
- voice->sound = voice->NextBlock;
- voice->length = min( voice->BlockLength, 0x8000 );
- voice->NextBlock += voice->length;
- voice->BlockLength -= voice->length;
- return( KeepPlaying );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetNextDemandFeedBlock
- Controls playback of demand fed data.
- ---------------------------------------------------------------------*/
- playbackstatus GUSWAVE_GetNextDemandFeedBlock
- (
- VoiceNode *voice
- )
- {
- if ( voice->BlockLength > 0 )
- {
- voice->sound += voice->length;
- voice->length = min( voice->BlockLength, 0x8000 );
- voice->BlockLength -= voice->length;
- return( KeepPlaying );
- }
- if ( voice->DemandFeed == NULL )
- {
- return( SoundDone );
- }
- ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
- // voice->sound = GUS_Silence16;
- // voice->BlockLength = 256;
- voice->length = min( voice->BlockLength, 0x8000 );
- voice->BlockLength -= voice->length;
- if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
- {
- return( KeepPlaying );
- }
- return( NoMoreData );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_Play
- Begins playback of digitized sound.
- ---------------------------------------------------------------------*/
- int GUSWAVE_Play
- (
- VoiceNode *voice,
- int angle,
- int volume,
- int channels
- )
- {
- int VoiceNumber;
- int type;
- int pan;
- unsigned flags;
- int ( *servicefunction )( int reason, int voice, unsigned char **buf, unsigned long *size );
- type = 0;
- if ( channels != 1 )
- {
- type |= TYPE_STEREO;
- }
- if ( voice->bits == 8 )
- {
- type |= TYPE_8BIT;
- type |= TYPE_INVERT_MSB;
- }
- voice->GF1voice = -1;
- angle &= 31;
- pan = GUSWAVE_PanTable[ angle ];
- if ( GUSWAVE_SwapLeftRight )
- {
- pan = 15 - pan;
- }
- voice->Pan = pan;
- volume = max( 0, volume );
- volume = min( 255, volume );
- voice->Volume = volume;
- if ( !GUS_Debug )
- {
- servicefunction = GUSWAVE_CallBack;
- }
- else
- {
- servicefunction = GUSWAVE_DebugCallBack;
- }
- VoiceNumber = gf1_play_digital( 0, voice->sound, voice->length,
- voice->mem, GUSWAVE_Volume - ( 255 - volume ) * 4, pan,
- voice->RateScale, type, &GUS_HoldBuffer, servicefunction );
- if ( VoiceNumber == NO_MORE_VOICES )
- {
- if ( GUS_Debug )
- {
- DB_printf( "Out of voices.\n" );
- }
- flags = DisableInterrupts();
- LL_AddToTail( VoiceNode, &VoicePool, voice );
- RestoreInterrupts( flags );
- GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
- return( GUSWAVE_Warning );
- }
- flags = DisableInterrupts();
- voice->GF1voice = VoiceNumber;
- voice->Active = TRUE;
- LL_AddToTail( VoiceNode, &VoiceList, voice );
- VoiceStatus[ VoiceNumber ].playing = TRUE;
- VoiceStatus[ VoiceNumber ].Voice = voice;
- if ( GUS_Debug )
- {
- DB_printf( "GUS voice %d playing\n", VoiceNumber );
- }
- RestoreInterrupts( flags );
- return( voice->handle );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_PlayVOC
- Begins playback of digitized sound.
- ---------------------------------------------------------------------*/
- int GUSWAVE_PlayVOC
- (
- char *sample,
- int pitchoffset,
- int angle,
- int volume,
- int priority,
- unsigned long callbackval
- )
- {
- int handle;
- int status;
- playbackstatus soundstatus;
- VoiceNode *voice;
- unsigned flags;
- // Make sure it's a valid VOC file.
- status = strncmp( sample, "Creative Voice File", 19 );
- if ( status != 0 )
- {
- // Tell multivoc that we had a bad VOC file
- MV_ErrorCode = MV_InvalidVOCFile;
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
- return( GUSWAVE_Error );
- }
- // Request a voice from the voice pool
- voice = GUSWAVE_AllocVoice( priority );
- if ( voice == NULL )
- {
- if ( GUS_Debug )
- {
- DB_printf( "No more voices. Skipping sound.\n" );
- }
- GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
- return( GUSWAVE_Warning );
- }
- voice->NextBlock = sample + *( unsigned short int * )( sample + 0x14 );
- voice->LoopStart = NULL;
- voice->LoopCount = 0;
- voice->BlockLength = 0;
- voice->PitchScale = PITCH_GetScale( pitchoffset );
- voice->wavetype = VOC;
- voice->bits = 8;
- voice->GetSound = GUSWAVE_GetNextVOCBlock;
- voice->length = 0;
- voice->next = NULL;
- voice->prev = NULL;
- voice->priority = priority;
- voice->callbackval = callbackval;
- soundstatus = GUSWAVE_GetNextVOCBlock( voice );
- if ( soundstatus == SoundDone )
- {
- flags = DisableInterrupts();
- LL_AddToTail( VoiceNode, &VoicePool, voice );
- RestoreInterrupts( flags );
- if ( GUS_Debug )
- {
- DB_printf( "Voice ended before playback.\n" );
- }
- // Tell multivoc that we had a bad VOC file
- MV_ErrorCode = MV_InvalidVOCFile;
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
- return( GUSWAVE_Error );
- }
- handle = GUSWAVE_Play( voice, angle, volume, 1 );
- return( handle );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_PlayWAV
- Begins playback of digitized sound.
- ---------------------------------------------------------------------*/
- int GUSWAVE_PlayWAV
- (
- char *sample,
- int pitchoffset,
- int angle,
- int volume,
- int priority,
- unsigned long callbackval
- )
- {
- VoiceNode *voice;
- int handle;
- int channels;
- int bits;
- int length;
- riff_header *riff;
- format_header *format;
- data_header *data;
- riff = ( riff_header * )sample;
- if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
- ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
- ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
- return( GUSWAVE_Error );
- }
- format = ( format_header * )( riff + 1 );
- data = ( data_header * )( ( ( char * )format ) + riff->format_size );
- if ( format->wFormatTag != 1 )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
- return( GUSWAVE_Error );
- }
- channels = format->nChannels;
- if ( ( channels != 1 ) && ( channels != 2 ) )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
- return( GUSWAVE_Error );
- }
- bits = format->nBitsPerSample;
- if ( ( bits != 8 ) && ( bits != 16 ) )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
- return( GUSWAVE_Error );
- }
- if ( strncmp( data->DATA, "data", 4 ) != 0 )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
- return( GUSWAVE_Error );
- }
- // Request a voice from the voice pool
- voice = GUSWAVE_AllocVoice( priority );
- if ( voice == NULL )
- {
- if ( GUS_Debug )
- {
- DB_printf( "No more voices. Skipping sound.\n" );
- }
- GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
- return( GUSWAVE_Warning );
- }
- voice->wavetype = WAV;
- voice->bits = bits;
- voice->GetSound = GUSWAVE_GetNextWAVBlock;
- length = data->size;
- voice->Playing = TRUE;
- voice->DemandFeed = NULL;
- voice->LoopStart = NULL;
- voice->LoopCount = 0;
- voice->length = min( length, 0x8000 );
- voice->BlockLength = length - voice->length;// min( loopend + 1, data->size );
- voice->sound = ( char * )( data + 1 );
- voice->NextBlock = voice->sound + voice->length;
- voice->next = NULL;
- voice->prev = NULL;
- voice->priority = priority;
- voice->callbackval = callbackval;
- voice->LoopStart = NULL;// voice->NextBlock + loopstart;
- voice->LoopEnd = NULL;//voice->NextBlock + min( loopend, data->size - 1 );
- voice->LoopSize = 0;//( voice->LoopEnd - voice->LoopStart ) + 1;
- voice->PitchScale = PITCH_GetScale( pitchoffset );
- voice->SamplingRate = format->nSamplesPerSec;
- voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
- handle = GUSWAVE_Play( voice, angle, volume, channels );
- return( handle );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_StartDemandFeedPlayback
- Begins playback of digitized sound.
- ---------------------------------------------------------------------*/
- int GUSWAVE_StartDemandFeedPlayback
- (
- void ( *function )( char **ptr, unsigned long *length ),
- int channels,
- int bits,
- int rate,
- int pitchoffset,
- int angle,
- int volume,
- int priority,
- unsigned long callbackval
- )
- {
- VoiceNode *voice;
- int handle;
- // Request a voice from the voice pool
- voice = GUSWAVE_AllocVoice( priority );
- if ( voice == NULL )
- {
- if ( GUS_Debug )
- {
- DB_printf( "No more voices. Skipping sound.\n" );
- }
- GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
- return( GUSWAVE_Warning );
- }
- voice->wavetype = DemandFeed;
- voice->bits = bits;
- voice->GetSound = GUSWAVE_GetNextDemandFeedBlock;
- voice->Playing = TRUE;
- voice->DemandFeed = function;
- voice->LoopStart = NULL;
- voice->LoopCount = 0;
- voice->BlockLength = 0;
- voice->length = 256;
- voice->sound = ( bits == 8 ) ? GUS_Silence8 : ( char * )GUS_Silence16;
- voice->NextBlock = NULL;
- voice->next = NULL;
- voice->prev = NULL;
- voice->priority = priority;
- voice->callbackval = callbackval;
- voice->PitchScale = PITCH_GetScale( pitchoffset );
- voice->SamplingRate = rate;
- voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
- handle = GUSWAVE_Play( voice, angle, volume, channels );
- return( handle );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_SetReverseStereo
- Set the orientation of the left and right channels.
- ---------------------------------------------------------------------*/
- void GUSWAVE_SetReverseStereo
- (
- int setting
- )
- {
- GUSWAVE_SwapLeftRight = setting;
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_GetReverseStereo
- Returns the orientation of the left and right channels.
- ---------------------------------------------------------------------*/
- int GUSWAVE_GetReverseStereo
- (
- void
- )
- {
- return( GUSWAVE_SwapLeftRight );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_InitVoices
- Begins playback of digitized sound.
- ---------------------------------------------------------------------*/
- static int GUSWAVE_InitVoices
- (
- void
- )
- {
- int i;
- for( i = 0; i < MAX_VOICES; i++ )
- {
- VoiceStatus[ i ].playing = FALSE;
- VoiceStatus[ i ].Voice = NULL;
- }
- VoicePool.start = NULL;
- VoicePool.end = NULL;
- VoiceList.start = NULL;
- VoiceList.end = NULL;
- for( i = 0; i < VOICES; i++ )
- {
- GUSWAVE_Voices[ i ].num = -1;
- GUSWAVE_Voices[ i ].Active = FALSE;
- GUSWAVE_Voices[ i ].GF1voice = -1;
- GUSWAVE_Voices[ i ].mem = NULL;
- }
- for( i = 0; i < VOICES; i++ )
- {
- GUSWAVE_Voices[ i ].num = i;
- GUSWAVE_Voices[ i ].Active = FALSE;
- GUSWAVE_Voices[ i ].GF1voice = 0;
- GUSWAVE_Voices[ i ].mem = gf1_malloc( GF1BSIZE );
- if ( GUSWAVE_Voices[ i ].mem == NULL )
- {
- GUSWAVE_MaxVoices = i;
- if ( i < 1 )
- {
- if ( GUSMIDI_Installed )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMemMIDI );
- }
- else
- {
- GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMem );
- }
- return( GUSWAVE_Error );
- }
- break;
- }
- LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
- }
- return( GUSWAVE_Ok );
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_SetCallBack
- Set the function to call when a voice stops.
- ---------------------------------------------------------------------*/
- void GUSWAVE_SetCallBack
- (
- void ( *function )( unsigned long )
- )
- {
- GUSWAVE_CallBackFunc = function;
- }
- /*---------------------------------------------------------------------
- Function: GUSWAVE_Init
- Initializes the Gravis Ultrasound for digitized sound playback.
- ---------------------------------------------------------------------*/
- int GUSWAVE_Init
- (
- int numvoices
- )
- {
- int status;
- if ( GUSWAVE_Installed )
- {
- GUSWAVE_Shutdown();
- }
- GUSWAVE_SetErrorCode( GUSWAVE_Ok );
- status = GUS_Init();
- if ( status != GUS_Ok )
- {
- GUSWAVE_SetErrorCode( GUSWAVE_GUSError );
- return( GUSWAVE_Error );
- }
- GUS_Debug = USER_CheckParameter( "DEBUGGUS" );
- GUSWAVE_MaxVoices = min( numvoices, VOICES );
- GUSWAVE_MaxVoices = max( GUSWAVE_MaxVoices, 0 );
- status = GUSWAVE_InitVoices();
- if ( status != GUSWAVE_Ok )
- {
- GUS_Shutdown();
- return( status );
- }
- GUSWAVE_SetReverseStereo( FALSE );
- GUSWAVE_CallBackFunc = NULL;
- GUSWAVE_Installed = TRUE;
- return( GUSWAVE_Ok );
- }
|