FIRST...load up QB with QB /L MSE_QB (for 4.5) or QBX /L MSE_PDS (for PDS)
This will load the BWSB library. Now, you can start writing your program. The first three major steps are going to be:
DEFINT A-Z '$INCLUDE: 'BWSB.BI' '$INCLUDE: 'GDMTYPE.BI'BWSB requires integers and those two include files to operate. Failure to follow these first few steps WILL RESULT IN A CRASH AND POSSIBLE LOSS OF DATA.
So, with that done, you'll want to keep the rest simple as well, and the best way of doing that is by following pre-built code. Here are a few declarations you'll want to make somewhere at the start of your module:
TYPE MSEConfigFile SoundCard AS INTEGER BaseIO AS INTEGER IRQ AS INTEGER DMA AS INTEGER SoundQuality AS INTEGER END TYPEThat section makes it easier to load the MSE driver file you choose. BWSB requires a driver file, called a Music and Sound Engine, or MSE for short. A file called MSE.CFG can be used to keep this data. However, this is not needed as you can write your own routines, but for now lets keep it simple.
DIM ModHead AS GDMHeaderModHead is used for the GDM module. It is used internally by BWSB, so no need to go into great detail, just make sure that code is added.
DIM SndDevMSE(6) AS STRINGThis is another part of the easy MSE load.
DIM MSEConfig AS MSEConfigFileThis is yet another part of the easy MSE load. In fact, this makes setting the device settings later SO much easier.
Freemem& = FRE(-1) - 80000 A& = SETMEM(-Freemem&)What this segment does is free up 80K of far heap memory. This is needed for the MSE files, plus the patterns. Don't worry if this doesn't make sense right now, if you need to know what this all means, consult the help file in QB.
SndDevMSE(1) = "GUS" 'Gravis Ultrasound SndDevMSE(2) = "SB1X" 'Sound Blaster 1.xx SndDevMSE(3) = "SB2X" 'Sound Blaster 2.xx SndDevMSE(4) = "SBPRO" 'Sound Blaster Pro SndDevMSE(5) = "SB16" 'Sound Blaster 16 SndDevMSE(6) = "PAS" 'Pro AudioSpectrum 16The six MSE files, this part is also part of the easy load.
OPEN "MSE.CFG" FOR BINARY AS 1 GET 1, , MSEConfig CLOSE 1In this last segment, the MSE.CFG file is opened and read. From here on in, its smooth sailing!
IF MSEConfig.SoundCard = 0 THEN PRINT "No Sound Selected in SETUP. Please run SETUP." END END IFIf a soundcard has not been specified, obviously sound will not be available!
MSE$ = SndDevMSE(MSEConfig.SoundCard) + ".MSE"Easy loading stuff again...
SELECT CASE MSEConfig.SoundQuality CASE 0: Ov = 16 CASE 1: Ov = 22 CASE 2: Ov = 45 CASE 3: Ov = 8 END SELECTMSEConfig.SoundQuality sets the variable Ov, which is the Oversampling rate at which sound plays. The higher the oversampling, the better sounding the music, but in most cases, the more processor time taken. The exception to this rule is the presence of a GUS card with 1MB or more of DRAM.
ErrorFlag = LoadMSE(MSE$, 0, Ov, 4096, MSEConfig.BaseIO, MSEConfig.IRQ, MSEConfig.DMA)This last fragment is all it takes to load the MSE. Also, it handles any errors that could occur, and many are possible!
SELECT CASE ErrorFlag CASE 0 CASE 1: PRINT "Base I/O address autodetection failure": END CASE 2: PRINT "IRQ level autodetection failure": END CASE 3: PRINT "DMA channel autodetection failure": END CASE 4: PRINT "DMA channel not supported": END CASE 6: PRINT "Sound device does not respond": END CASE 7: PRINT "Memory control blocks destroyed": END CASE 8: PRINT "Insufficient memory for mixing buffers": END CASE 9: PRINT "Insufficient memory for MSE file": END CASE 10: PRINT "MSE has invalid identification string (corrupt/non-existant)": END CASE 11: PRINT "MSE disk read failure": END CASE 12: PRINT "MVSOUND.SYS not loaded (required for PAS use)": END CASE ELSE: PRINT "Unknown error on MSE startup" + STR$(ErrorFlag): END END SELECTThis last section is a monstrous error-notice. If the ErrorFlag is 0, then the operation is a success. If anything goes wrong, the program will quit with an error. If this is not done, the computer will lock up. This could be trimmed to just quit if ANY error occurred.
IF LEN(COMMAND$) = 0 THEN INPUT "Module file: ", ModFile$ ELSE ModFile$ = COMMAND$Here is the example from MMP.BAS about how to specify a filename. All you have to do really is set ModFile$. This can be done in a number of ways, this is just one of them.
TestMOD: IF LEN(ModFile$) = 0 THEN END IF INSTR(ModFile$, ".") = 0 THEN ModFile$ = ModFile$ + ".GDM"This last fragment of code is MMP.BAS's way of 'testing' the filename.
IF EmsExist THEN ErrorFlag = 1 ELSE ErrorFlag = 0One of the greatest assets to BWSB is its use of EMS. It can allocate as much EMS as it needs to play sound files, up to the RAM limit in your computer.
File = FREEFILEA great way of determining a file handle to open is by using the FREEFILE command. It will open the next available file handle. Available file handles are set by the FILES line in CONFIG.SYS.
OPEN ModFile$ FOR BINARY AS FileGDM files are stored in binary format, so open it as such.
LoadGDM FILEATTR(File, 2), 0, ErrorFlag, VARSEG(ModHead), VARPTR(ModHead)Load that sucker up! And go through extensive error testing...
SELECT CASE ErrorFlag CASE 0 CASE 1: PRINT "Module is corrupt": END CASE 2: PRINT "Could not autodetect module type": END CASE 3: PRINT "Bad format ID": END CASE 4: PRINT "Out of memory": END CASE 5: PRINT "Cannot unpack samples": END CASE 6: PRINT "AdLib samples not supported": END CASE ELSE: PRINT "Unknown Load Error:" + STR$(ErrorFlag): END END SELECTErrors R Us...attempting to play a corrupt GDM file leads to disaster!
MusicChannels = 0 FOR J = 1 TO 32 IF ASC(MID$(ModHead.PanMap, J, 1)) <> &HFF THEN MusicChannels = MusicChannels + 1 END IF NEXTHere, the program uses a sneaky way of detecting how many channels to allocate. BWSB can allocate up to 32 channels, but unless you're using a GUS card, more channels means more CPU power.
OverRate& = StartOutput(MusicChannels, 0)Here, the output is initialized. Only one step left to getting the music going...
StartMusicHow simple! Whew! What a simple final step.
Now, when you wish to cancel the music, you should do this:
StopMusic StopOutput UnloadModule FreeMSEFreeMSE should only be used when you no longer need sound, like when you are ending the program. However, one of the nice things about QB is that FreeMSE is called when QB ends a program, so calling it is not really necessary. How- ever, it is ALWAYS a good idea to call it anyways...you just never know!
So, if you wish, just cut and paste the code into your program! It's that simple. Oh, and be sure to use the SETUP.EXE program that comes with the BWSB package to configure your MSE.CFG file. As it stands, using this code without an MSE.CFG file will make it lock up! So, use the SETUP.EXE or add error detection in the loading (more on that later...)
Woohoo! This completes the hardest part of using BWSB! If you can master this
then the rest is easy.