Author Topic: sound effects in qb64 - can anyone recommend any good demos or examples?  (Read 3912 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
I know how to make simple notes and beeps,
now I'm looking for examples of generating other sounds,
not playing back sound files, but generating sounds with commands
(like you would with the C64 SID chip), i.e.
  • play multiple sounds at once (3+ oscillators)
  • set ADSR per oscillator
  • wave shapes: Square, Triangle, Saw, Noise, etc.
  • HP, BP, LP filters
  • Any other effects, etc.

I'm really just looking for example code I can run and play with...
Thanks

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Are you interested in fart sounds? Oh wait, you need FreeBASIC for that!
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Check through Petr's posts, as far as I know he doesn't fart around with sound.

Also he and _vince were having a discussion on sound creation, I think I recall.

yes, I found this:
https://www.qb64.org/forum/index.php?topic=3508.msg128331#msg128331

This looks even better:
https://www.qb64.org/forum/index.php?topic=2494.msg117307#msg117307
« Last Edit: April 10, 2021, 02:14:47 pm by bplus »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Hi guys.
I know that I almost never contribute now, but I spend all my free time working on our housing now. I recommend using the _SNDRAW command to build a sound wave with any waveform. All you have to do is insert sound samples in the range from -1 to 1 into the sound field (create a saw wave in this way) and then play it with _SNDRAW. Of course, it is necessary to take into account the stereo error of the _SNDRAW command and therefore it is possible to save the sound using my SaveSound program as WAV (it is available in the programs referenced by BPlus).

Sinus wave example:
Code: QB64: [Select]
  1. 'sinus waveform create and play:
  2. SCREEN _NEWIMAGE(1024, 768, 32)
  3.  
  4. SoundLenght = 10 '10 seconds
  5. SoundRate = _SNDRATE '44100 samples per second
  6.  
  7. Samples = SoundRate * SoundLenght
  8.  
  9. DIM WAV(Samples) AS SINGLE
  10.  
  11. FOR GenerateSound = 0 TO Samples
  12.     e = e + .001 * _PI(2)
  13.     WAV(GenerateSound) = SIN(e)
  14.  
  15. PSET (384, 0)
  16. FOR PlaySound = 1 TO Samples
  17.     LOCATE 1
  18.     IF PlaySound MOD 3000 = 0 THEN PRINT "Time:"; PlaySound \ _SNDRATE: _DISPLAY
  19.     X = X + 1
  20.     IF X > 1024 THEN X = 0
  21.     LINE (X, 0)-(X, 768), &HFF000000, BF
  22.     LINE (X - 1, 384 + WAV(PlaySound - 1) * 150)-(X, 384 + WAV(PlaySound) * 150)
  23.     _SNDRAW WAV(PlaySound)
  24.     DO UNTIL _SNDRAWLEN = 0: LOOP
  25.  

and something else with small modification...

Code: QB64: [Select]
  1. 'sinus waveform create and play:
  2. SCREEN _NEWIMAGE(1024, 768, 32)
  3.  
  4. SoundLenght = 10 '10 seconds
  5. SoundRate = _SNDRATE '44100 samples per second
  6.  
  7. Samples = SoundRate * SoundLenght
  8.  
  9. DIM WAV(Samples) AS SINGLE
  10.  
  11. FOR GenerateSound = 0 TO Samples
  12.     e = e + .01 * _PI(2) * RND * TAN(f)
  13.     f = f + .001
  14.     WAV(GenerateSound) = SIN(e)
  15.  
  16. PSET (384, 0)
  17. FOR PlaySound = 1 TO Samples
  18.     LOCATE 1
  19.     IF PlaySound MOD 3000 = 0 THEN PRINT "Time:"; PlaySound \ _SNDRATE: _DISPLAY
  20.     X = X + 1
  21.     IF X > 1024 THEN X = 0
  22.     LINE (X, 0)-(X, 768), &HFF000000, BF
  23.     LINE (X - 1, 384 + WAV(PlaySound - 1) * 150)-(X, 384 + WAV(PlaySound) * 150)
  24.     _SNDRAW WAV(PlaySound)
  25.     DO UNTIL _SNDRAWLEN = 0: LOOP
  26.  
« Last Edit: April 10, 2021, 05:38:34 pm by Petr »

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
If you want typical "8 bit" type sound effects, then I would recommend, www.bfxr.net.  The application can be used both on and offline. Runs on Windows but runs perfectly on Linux Mint 20 using Wine. Did I mention that it's free? I know... It sounds like a shameless advertising plug... but you did ask... lol
Logic is the beginning of wisdom.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Thanks everyone for your replies... I will check out those examples.
This is mainly for simple sound effects for games.
Maybe down the line I'd be interested in writing a custom sequencer or tracker
(the standard commercial programs like Garage Band and Cakewalk never felt intuitive to me, like how I see music in my head).
For now I am just looking for basic sounds for games, beyond Pong-like beeps.
I'll check out what everyone suggests and post back later.
Thanks again!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
@madscijr

Hi again, here is next example + sub for saving this mono sound as wav:

Code: QB64: [Select]
  1. 'sinus waveform create and play + save output as 16 bit mono WAV file:
  2. SCREEN _NEWIMAGE(1024, 768, 32)
  3.  
  4. SoundLenght = 10 '10 seconds
  5. SoundRate = _SNDRATE '44100 samples per second
  6.  
  7. Samples = SoundRate * SoundLenght
  8.  
  9. DIM WAV(Samples) AS SINGLE
  10.  
  11. FOR GenerateSound = 0 TO Samples
  12.     e = e + .001 * _PI(2) * TAN(f)
  13.     f = f - .0001
  14.     WAV(GenerateSound) = SIN(e)
  15.  
  16.  
  17. FOR PlaySound = 1 TO Samples
  18.     LOCATE 1
  19.     IF PlaySound MOD 3000 = 0 THEN PRINT "Time:"; PlaySound \ _SNDRATE: _DISPLAY
  20.     X = X + 1
  21.     IF X > 1024 THEN X = 0
  22.     LINE (X, 0)-(X, 768), &HFF000000, BF
  23.     LINE (X - 1, 384 + WAV(PlaySound - 1) * 150)-(X, 384 + WAV(PlaySound) * 150)
  24.     _SNDRAW WAV(PlaySound)
  25.     DO UNTIL _SNDRAWLEN = 0: LOOP
  26.  
  27. PRINT "Saving effect as EFFECT1.WAV"
  28. SAVESOUND16M WAV(), "EFFECT1.WAV"
  29.  
  30.  
  31. SUB SAVESOUND16M (arr() AS SINGLE, file AS STRING) 'save MONO 16 bit WAV audio
  32.  
  33.     TYPE head16
  34.         chunk AS STRING * 4 '       4 bytes  (RIFF)
  35.         size AS LONG '              4 bytes  (file size)
  36.         fomat AS STRING * 4 '       4 bytes  (WAVE)
  37.         sub1 AS STRING * 4 '        4 bytes  (fmt )
  38.         subchunksize AS LONG '      4 bytes  (lo / hi), $00000010 for PCM audio
  39.         format AS INTEGER '         2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
  40.         channels AS INTEGER '       2 bytes  (1 = mono, 2 = stereo)
  41.         rate AS LONG '              4 bytes  (sample rate, standard is 44100)
  42.         ByteRate AS LONG '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
  43.         Block AS INTEGER '          2 bytes  (block align = number of channels * bits per sample /8)
  44.         Bits AS INTEGER '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
  45.         subchunk2 AS STRING * 4 '   4 bytes  ("data")  contains begin audio samples
  46.         lenght AS LONG '            4 bytes  Data block size
  47.     END TYPE '                     44 bytes  total
  48.     DIM H16 AS head16
  49.     ch = FREEFILE
  50.  
  51.     H16.chunk = "RIFF"
  52.     H16.size = 44 + UBOUND(arr) * 2 '1 channel, it create 16 bit, stereo wav file, one sample use 2 bytes for one channel
  53.  
  54.     H16.fomat = "WAVE"
  55.     H16.sub1 = "fmt "
  56.     H16.subchunksize = 16
  57.     H16.format = 1
  58.     H16.channels = 1
  59.     H16.rate = 44100
  60.     H16.ByteRate = 44100 * 16 / 8
  61.     H16.Block = 2
  62.     H16.Bits = 16
  63.     H16.subchunk2 = "data"
  64.     H16.lenght = UBOUND(arr) * 2
  65.     IF _FILEEXISTS(file$) THEN KILL file$
  66.  
  67.     OPEN file$ FOR BINARY AS #ch
  68.     PUT #ch, , H16
  69.     DIM LeftChannel AS INTEGER
  70.  
  71.     FOR audiodata = 0 TO UBOUND(arr)
  72.         LeftChannel = arr(audiodata) * 16384
  73.         PUT #ch, , LeftChannel
  74.     NEXT
  75.     CLOSE ch
  76.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Hi Madscijr

I remember a .BAS in the folder of the demonstration of Qb45. If you have it you can get that file demo.
on the web I find this library for QB, herehttps://www.qbasic.net/en/qbasic-downloads/libraries/sound-music.htm
while here https://qb45.org/files.php?cat=9 you find more resource for QB45 in the description it may be interesting Music20, File2MID and Ruckus for your goal.
While in this Pete's ocean https://www.tapatalk.com/groups/qbasic/ you can search anything!

for QB64 it is possible to use the new features as Petr is showing to you.

Programming isn't difficult, only it's  consuming time and coffee

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
I got some of the samples to work, though that approach seems way more complicated than I was looking for, or expected, having done SID sounds on a C64 back in the day. I'm not interested in generating or playing back WAV files - aren't there any built in commands to just generate sound at a given frequency and waveform on a particular channel?
Guess I'll keep messing with those example and searching through code, and when I find something close, I'll post it... Thanks guys

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Basic statements for generate sound are SOUND and PLAY. Play is statement for creating music using notes. For opening music files it is _SNDOPEN, for access to raw audiodata (from sound file opened with _SNDOPEN) it is function _MEMSOUND. For creating own sound wave and playing it is here _SNDRAW.

I can't give you any own example for the PLAY command because I didn't deal with it. All I know is that it can play background music and also several notes at once. I'm adding a quick demonstration to the SOUND statement.

Code: QB64: [Select]
  1. FOR r = 1 TO 100
  2.     FOR a = 210 TO 310 STEP 10
  3.         SOUND a, .1
  4.         SOUND 1000 - a, .2
  5.     NEXT
  6.  

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Basic statements for generate sound are SOUND and PLAY. Play is statement for creating music using notes. For opening music files it is _SNDOPEN, for access to raw audiodata (from sound file opened with _SNDOPEN) it is function _MEMSOUND. For creating own sound wave and playing it is here _SNDRAW.

I can't give you any own example for the PLAY command because I didn't deal with it. All I know is that it can play background music and also several notes at once. I'm adding a quick demonstration to the SOUND statement.

Code: QB64: [Select]
  1. FOR r = 1 TO 100
  2.     FOR a = 210 TO 310 STEP 10
  3.         SOUND a, .1
  4.         SOUND 1000 - a, .2
  5.     NEXT
  6.  

That works, thanks. I have been going through code looking at how different sounds are made.
It seems the SOUND statement can do a lot!
I haven't seen a good example of using it to create white noise (like an explosion sound), and also can you control the volume with it?
Thanks again.