×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Playing background WAVE files in a QBASIC RPG

Playing background WAVE files in a QBASIC RPG

Playing background WAVE files in a QBASIC RPG

(OP)
For the last year or so, I've been working on an RPG of mine.  I've put a lot of work into it, and the only thing I feel that keeps it from having that final "professional" touch is the fact that it's dead silent.  I would love to use wave files for sound effects and for background music.  Can anyone guide me in the right direction as to how to go about doing this?
Thanks for any help that you can give.

RE: Playing background WAVE files in a QBASIC RPG

there are lots of wave players out there for qb.  try dmawave, or check out the ff2 clone.  try a google search for qb and wave.

RE: Playing background WAVE files in a QBASIC RPG

(OP)
I have no idea where to find any of those programs you mentioned.  I did internet searches and came up with nothing.
As far as just searching for a qbasic wave file player on google, we're looking at about 5000 or more matches, and about 1% of them have anything of any interest, if that.  
No offense, but any more concrete help would be greatly appreciated.

RE: Playing background WAVE files in a QBASIC RPG

This plays wave files flawlessly on every computer that I have tried it on.  The wavs can be any length that you want.

These are the specifications of the wav
PCM format
176kbps bit rate
8 bit sample size
mono
22kHz sample rate

This format can be made by Windows Sound recorder, I could give you a sample wav to try if you would like.



DECLARE SUB wave (wav$)
DECLARE SUB SBDETECT ()
DECLARE SUB RESETDSP ()
DECLARE SUB DMAPLAY (Segment&, Offset&, buflen&)
DECLARE SUB GetBLASTER (DMA, BasePort, IRQ)
DECLARE SUB WRITEDSP (ibyte)
DECLARE SUB playmusic ()
COMMON SHARED repeat, buflen&
COMMON SHARED BasePort, LenPort, Channel, nosound
DIM SHARED aa!
CONST timeconst = 256 - 1000000 \ 22050
'$DYNAMIC
DIM SHARED WavBuffer(0 TO 0) AS STRING * 32767
'$STATIC
DIM SHARED snds(1 TO 6) AS STRING * 30
wave wav$
a! = LOF(2)
DO
IF nosound = 0 THEN playmusic
aa! = aa! + 32767
LOOP UNTIL aa! >= a!

SUB DMAPLAY (Segment&, Offset&, buflen&)
Page = 0
MemLoc& = Segment& * 16 + Offset&
SELECT CASE Channel
    CASE 0
       PgPort = &H87
       AddPort = &H0
       LenPort = &H1
       ModeReg = &H48
    CASE 1
       PgPort = &H83
       AddPort = &H2
       LenPort = &H3
       ModeReg = &H49
    CASE 2
       PgPort = &H81
       AddPort = &H4
       LenPort = &H5
       ModeReg = &H4A
    CASE 3
       PgPort = &H82
       AddPort = &H6
       LenPort = &H7
       ModeReg = &H4B
END SELECT
OUT &HA, &H4 + Channel
OUT &HC, &H0
OUT &HB, ModeReg
OUT AddPort, MemLoc& AND &HFF
OUT AddPort, (MemLoc& AND &HFFFF&) \ &H100
IF (MemLoc& AND 65536) THEN Page = Page + 1
IF (MemLoc& AND 131072) THEN Page = Page + 2
IF (MemLoc& AND 262144) THEN Page = Page + 4
IF (MemLoc& AND 524288) THEN Page = Page + 8
OUT PgPort, Page
OUT LenPort, buflen& AND &HFF
OUT LenPort, (buflen& AND &HFFFF&) \ &H100
OUT &HA, Channel
WRITEDSP &H40
WRITEDSP timeconst
WRITEDSP &H14
WRITEDSP (buflen& AND &HFF)
WRITEDSP ((buflen& AND &HFFFF&) \ &H100)
END SUB

SUB GetBLASTER (DMA, BasePort, IRQ)
IF LEN(ENVIRON$("BLASTER")) = 0 THEN PRINT "BLASTER environment variable not set.": EXIT SUB
FOR Length = 1 TO LEN(ENVIRON$("BLASTER"))
   SELECT CASE MID$(ENVIRON$("BLASTER"), Length, 1)
      CASE "A"
        BasePort = VAL("&H" + MID$(ENVIRON$("BLASTER"), Length + 1, 3))
      CASE "I"
        IRQ = VAL(MID$(ENVIRON$("BLASTER"), Length + 1, 1))
      CASE "D"
        DMA = VAL(MID$(ENVIRON$("BLASTER"), Length + 1, 1))
   END SELECT
NEXT
END SUB

SUB playmusic
  DEF SEG
  RESETDSP
  IF repeat >= 0 THEN DMAPLAY VARSEG(WavBuffer(0)), VARPTR(WavBuffer(0)), buflen&
  IF EOF(2) THEN
    SEEK #2, 44
    IF repeat <= 0 THEN repeat = repeat - 1
  END IF
  buflen& = LOF(2) - LOC(2)
  IF buflen& > 32767 THEN buflen& = 32767
  GET #2, , WavBuffer(0)
END SUB

SUB RESETDSP
OUT BasePort + 6, 1
FOR Count = 1 TO 4
   junk = INP(BasePort + 6)
NEXT
OUT BasePort + 6, 0
END SUB

SUB SBDETECT
nosound = 1
FOR port = &H210 TO &H280 STEP &H10
  OUT port + &H6, 1
  FOR Count = 1 TO 100
    OUT port + &H6, 0
    Stat = INP(port + &HE)
    Stat = INP(port + &HA)
    IF Stat = &HAA THEN nosound = 0: EXIT SUB
  NEXT Count
NEXT port
IF nosound = 1 THEN
   PRINT "Sound Blaster not detected. Do you"
   PRINT "wish to disable sound? (y,n)"
   DO: sel$ = INKEY$: LOOP WHILE UCASE$(sel$) <> "Y" AND UCASE$(sel$) <> "N"
   IF UCASE$(sel$) = "N" THEN END
END IF
END SUB

SUB wave (wav$)
IF wav$ = "" THEN EXIT SUB
DEF SEG
SBDETECT
IF nosound = 0 THEN
  GetBLASTER Channel, BasePort, IRQ
  RESETDSP
END IF
OPEN wav$ + ".wav" FOR BINARY AS #2
GET #2, , WavBuffer(0): buflen& = 32767
END SUB

SUB WRITEDSP (ibyte)
DO: LOOP WHILE INP(BasePort + 12) AND &H80
OUT BasePort + 12, ibyte
END SUB

RE: Playing background WAVE files in a QBASIC RPG

(OP)
Thanks for the music player!
Although, I have some questions.  Your specifications said:

8-bit
22k Hz
mono

But then you said it had to be of 176kbps.  When you convert a wave to 8bit mono, 22kHz, it's only 21kbps.  The only reason I'm questioning this is because when I play a song that I've converted, it sounds right, but it skips.  It'll play a 2 minute song in about 15 seconds because it keeps jumping through the song.  It'll play 3 seconds of the song, skip, play another 3 seconds, skip, etc...

Do you know why this might be?  Or what I can do to convert the song just right?
Thanks for your help, it's much appreciated. :)

(Secondly, I haven't tried it, is there any way that this wave file code can be running in the background if my main code?  Thanks again.)

RE: Playing background WAVE files in a QBASIC RPG

Actually its 22 KBps, kiloBYTES = 176 kiloBITs.


Your second question, yes.  You will just have to count the ticks of the TIMER, every 27 ticks you will have to call playmusic.  The way that the wav player above works is it send 32767 bits to the sound card, which lays it automatically, qbasic doesn't actually play anything.  You will notice that if you end the program in the middle of one of the 32767 bit sections it will continue playing that section.

I don't see why it skips through the song, it doesn't for me.  You must have the wrong format; I copy and pasted the code directly, so its not wrong.

RE: Playing background WAVE files in a QBASIC RPG

(OP)
Would you be able to send me that sample wave file?  I probably just need to do some tweaking with the format and could use the example to base it on.

RE: Playing background WAVE files in a QBASIC RPG

(OP)
I've been trying some things.
I'm not sure if it's the format that's incorrect (although, I'd still appreciate a working sample.  Email address milesaway1980@juno.com).

But if I change the kHz to anything but 22050, the speed is wrong, if I change the bits to 16 instead of 8, it's really staticy, and if I change it to stereo instead of mono, it's really slow.  So I know that the format has to be correct through process of elimination.  It's just that it plays about 2 seconds of the song and then skips ahead like 30 seconds.  (It doesn't start from the beginning of the wave file either.)

Could that possibly have anything to do with me using Windows XP?  I doubt it, but no harm in checking.

RE: Playing background WAVE files in a QBASIC RPG

Unfortunately there is no pure QB way of playing a waw IN THE BACKGROUND.
Qbasicking code will work as long as you dont ask QB to do other things as draw tiles, move sprites and read keyboard. And even if the code is tweaked to match your sample it may not work ok in all computers.
To work  OK a Soundblaster needs an Interrupt Service Routine (ISR) filling its buffer at the right pace, independently of what your program is doing. If you don't do it the sound skips, ckicks and does weird things.
 An ISR CAN'T be done in QB, it must be done in assembler or C. So the best way of having sound in QB is by using a pre-made library. You have multichannel mixers in DirectQB  or UGL, and a single channel in Future.

Before deciding to use a pure QB solution try it in real-life conditions, merge it with your game and see how the sound and the game behave...
 

Antoni
http://www.geocities.com/antonigual/index.html

RE: Playing background WAVE files in a QBASIC RPG

Sandman,
I agree with Antoni that a premade library is the best way to go, but I've recently read some posts by v1ctor (author of the UGL library) on the NeoBASIC board that suggests that a Pure QB solution is possible.  However, it doesn't have the benefit of being able to run in the IDE. Here are the links to the posts (they will disappear soon, so read it now).
http://www.neozones.com/Board/Messages/54502.shtml
http://www.neozones.com/Board/Messages/54503.shtml

The basic trick is that you write QB code that has a call to the (QB ISR) function immediately after a ProcPtr() call.  The ProcPtr function then gets the address of the instruction in the caller subroutine (that called both the QBISR() and ProcPtr()) where the ProcPtr() call was executed.  Now it scans downward in the machine code in memory to find the call to the QBISR() to get its function pointer, and removes the call (to prevent the ISR from being executed before the interrupt vector table is set up).  It's a hack, but it solves the "getting the address of a QB function in PureQB" problem.  Now the other problem is that the QBISR() function doesn't have an IRET instruction at the end of the function.  This would cause the OS (or DOS Box) to crash when the ISR is called.  Now, there are two ways to solve this.  One is to modify the machine code at the end of the QBISR() sub to replace a RETF with an IRET (might also have to change the prologue and epilogue code to save extra registers).  The other way is to write an assembler ISR stub to save the important registers, call the QB subroutine, and restore registers and IRET.  This can be stored into memory using a QB string or array, and the interrupt vector table can be modified to point to this SUB.  There is no need to call the subroutine directly, so no CALL ABSOLUTE should be needed.  (If there is a need to call an assembler subroutine without using CALL ABSOLUTE, Plasma offered a solution which involves overwriting the machine code of a QB library function e.g. SLEEP and calling the library function).

Don't you think this is too much work just to get background sound playing working?  However, if you still want to go the QB way, here is some code that uses an assembler ISR and polling to achieve very good background sound in compiled programs.  But don't expect it to be compatible with all sound cards.

For SB4.0 compatibles, use
http://michaelrs.homepage.dk/download/Sbdsp4xx.zip
For WinXP or SB2.0 compatibles, use
http://michaelrs.homepage.dk/download/Sbdsp2xx.zip



RE: Playing background WAVE files in a QBASIC RPG

(OP)
Thanks for all the information on that.  Definitely a bit too much work for a pure QB method of playing wave files.  If I went that route, I don't know enough about how sound cards work to be able to do all the things you mentioned.  I'm not really all about having pure QB code playing the wave file, just as long as I can get the program/game itself to get some wave files playing (without having to shrink down the game [Qbasic] and play them with Winamp or something.)
Something like qbasicking's wave file player would also be good if I could just somehow tweak it to get it to work right on my computer.  It plays wave files, but it plays just pieces of them.  It'll play about 3 seconds worth, skip 30 seconds, play another 3 seconds worth, etc.. and a 3 minute song will be done in about 15 seconds.  (I'm using a Sound Blaster Live 5.1 soundcard with Windows XP if anyone has any ideas.)
Secondly, if a library works too, that'd be great, although, I've never used a library before in QBasic, so some help with that would be appreciated.  Also, I don't know where to find such libraries.  I've done searches on the internet "Qbasic Wave library" and other such variations but haven't come up with much.
Thanks for everyone's help.

RE: Playing background WAVE files in a QBASIC RPG

http://www.rpg-dev.net/projects.php?action=download&id=...

there's a wav player somewhere in here.  I dunno,i think you can play it in background (it has a very long wav in here, yet i can move the cursor key while it's playing.)  i consider it one of the better pure qb wav players.

RE: Playing background WAVE files in a QBASIC RPG

Might I add that even a pure DOS solution would cause more problems than it would solve? Look up DS4QB or it's descendants, DS4QB2 and DS4QB++. One of them (I can't remember which) will run flawlessly on all windows systems from 95 to XP. Speaking from experience, if you don't get a perfect system the first time around, you'll end up switching a lot to find one that works, so be careful with your choice.

RE: Playing background WAVE files in a QBASIC RPG

Glad to meet you, Toshi!

And to complete the information:
 
To use a soundcard from a DOS program in Windows 2000 or XP is not possible, unless you install VDMSound.  This thing emulates the API of a SoundBlaster 16 in any soundcard that's currently working with Windows Media.

Antoni
http://www.geocities.com/antonigual/index.html

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close