in QBasic, it was possible to play sound tones of any frequency through the PC speaker.

Is it possible to do something similar with FMOD, but then through the soundcard instead of PC Speaker?

So in fact my question is, how to generate some sound with FMOD that doesn’t come from loading a wav, ogg, mp3 or whatever file from HD?

And what’s the best way to let it play this sound continiously while also displaying realtime graphics, (like demos)


  • You must to post comments

Check out the Sinemouse_0.1.ZIP from the /fmod-directory of http://public.2mal2mal.de/

The source is in PB but easy to understand.

  • You must to post comments

Thanks, it looks to be kind of what I was looking for, and it seems possible to easily change it to a triangle wave etc…

There’s something about the code I don’t understand.

SetGadgetText(1,"Y-Mouseposition: " + Str(mpos\y))
SetGadgetText(3,Str(fq)+" Hz")
Until WindowEvent() = #PB_Event_CloseWindow [/code:37tn4rgk]

This is the main loop right? But in this main loop there’s no function to generate the stream, or not even something that would look like being able to change the frequency of the sound when you move the mouse, all it contains is putting the text on the window!

How can this program be doing something (namely changing the frequency of the sound I hear when I move the mouse) that is not in this loop that it’s stuck in?


P.S. I’m coding in C++ myself. I’ve used QBasic some time ago. The PB code doesn’t really look much like QBasic at all.

  • You must to post comments

There’s no call inside the mainloop to update the stream, because the stream is realized as a callback.
One important line is the following:
[code:2kild4p9]hStream.l = FSOUND_Stream_Create(@BufferCallback(), buffer_size, wavetype, samplerate, 0) [/code:2kild4p9]
Here a new stream is created and as first parameter the adress (@) of the procedure (PB-name for a ‘function’) is overgiven.
When this stream is played, fmod itself calls periodically this procedure, which then has to fill the buffer with data. The procedure has to be of the form:
[code:2kild4p9]Procedure.l BufferCallback(hStream.l, *BufferPointer.l, length.l, param.l) [/code:2kild4p9]
(‘.l’ means return long, ‘
‘ signs a pointer to something)
So this procedure is called depending of the actual buffersize a lot of times per second as long as the stream is played and is expected to fill it with RAW-Data.

In the main loop you could handle STOP and PLAY on this stream using FSOUND_Stream_*, but you never have to call this callback-function manually.

On the contrary to analog technology a saw (even a ‘real’) one is even more simple to implement (but might sound too ‘clean’ for you)
Just increase inside the callback the 16-Bit-samplevalue from -32768 linear to 32767 by a summand depending on the frequency (and if it exceeds the maximum just add -32768). If you then combine 4 or 5 of this saw-waves with an interval of octaves or quintes it sounds really FAT!
Or of course triangle or rect or random or whatever. ๐Ÿ˜€

P.S.: For some more [url=http://www.purebasic.com:2kild4p9]information on PB have a look here[/url:2kild4p9]. It has nothing to to with Qbasic (or GW-Basic ๐Ÿ˜‰ ) or VB. It’s just the syntax using BASIC-typical commands.

  • You must to post comments

[quote="brett":1pnuq55r]there is a thread here … n+generate
where i show how to generate a sine wave at a specific frequency at any output rate[/quote:1pnuq55r]

Thanks, that’s working and generating a pure tone indeed :)

I’ve tried some things myself too, but the tone I get sounds very blocky and full of interuptions here and there. I used the following code (in there, I’m once again amazed how it is like two functions are running at once and things outside the while loop immediatly react on changes of the value of “t”):


include <stdio.h>

include <math.h>

include <conio.h>

include <windows.h>

include "fmod.h"

include "fmod_errors.h"

double t=0;

signed char F_CALLBACKAPI streamcallback(FSOUND_STREAM *stream, void *buff, int len, int param)
int count;
signed short *buffer = (signed short *)buff;

for (count=0; count&lt;len&gt;&gt;1; count++)
    buffer[count] = (signed short)(sin(count/16.0*(1+t)) * 16384.0f);    
return 1;


int main()

if (FSOUND_GetVersion() &lt; FMOD_VERSION) return 1;
if (!FSOUND_Init(44100, 16, 0)) return 1;

stream = FSOUND_Stream_Create(streamcallback, 6*2048, FSOUND_NORMAL | FSOUND_16BITS | FSOUND_16BITS, 44100, 12345);
if (!stream)  return 1;

if (FSOUND_Stream_Play(FSOUND_FREE, stream) == -1) return 1;



return 0;


How comes it that my sine function is sounding so “blocky” (also if I don’t multiply it by (1+t),so for example “buffer[count] = (signed short)(sin(count/8.0*(1+t)) * 16384.0f);” doesn’t sound pure at all)
Appearantly you have to do something with a “speed” and increase t1 and t2 all the time to get a pure tone, but what’s the reason behind this?

buffer[count] = (signed short)(((count/64)%2) * 16384.0f); generates a pure tone too, but only as long as count is divided through something that’s a power of two, if it’s not not a power of two, this sounds blocky too, what’s the explanation for that?

And another question, how to know what the actual length of the “buff” will be, because I’ve had to experiment with values for that bitshift with len to get the program not crash (I guessed it had to be different for mono and stereo sound, I used mono in that code).


EDIT: by “blocky” I mean that there are CLICKS all the time

EDIT2: what I’m trying to create is a “chiptune” kind of song, do you know of any good tutorial about manually creating nice sound streams?

EDIT3: sorry for all the edits, but… Appearantly if I copypaste your code into my mono channel sound and tinker a bit to get it not crash, it has clicks as well :( Why?

  • You must to post comments

Some basics:
1. using a fixed frequency:
A near to Physics formula would be something like:
buffer[count] = (signed short)(16384.0f * sin(2 * pi * frequency[Hz] * timeposition[globalSampleposition] / samplingrate);

If instead of a global timeposition-value a local value e.g. count is used to calculate the sinewave the problem is, that your counter starts always at 0 when the callback-routine is started, so your callback creates always a sine-wave with the beginning value of sin(0) = 0. (btw: with count/64%2 you create a saw-wave, but the rules for the wavelength are the same)
But one buffer follows direct the previous regardless of the last written sinewave-value. So in most cases the last value written in the previous buffer is far away from 0, but the first one from the next buffer starts at 0 again, so there’s an audible click at every bufferstart. Only if it is divided by a power of two it mostly fits perfect into one bufferlength, which has always a length of a power of two, too.
You can solve this using the global ‘timeposition’-variable that is increased by 1 inside your count-loop and which is used for the sine.
(To prevent an overflow while playing billions of samples you should reset the timeposition-variable to 0 from time to time, but only when sin(2pifrequency*timeposition/samplerate) is nearly exactly 0 to avoid clipping again. But you might ignore this, because if you use e.g. an unsigned 32-Bit-integer for the timeposition-value at 44100 Hz samplingrate the overrun would occur after ~1200 hours non-stop-playing)

  1. using an Realtime-changing frequency:
    Then forget about point 1 ๐Ÿ˜‰
    No, not really, but you have to improve it, because always when you change the frequency inside the callback, the last sin-value of the old frequency is mostly total different to the first one of the new frequency. So there’s always an audible click when changing the frequency.
    To solve this problem easily there’s a basic knowledge of sinewaves neccessary. Each sinewave can be interpretated as the sequence of x-values (the ‘real’ part) and each cosinewave as the y-value(the ‘imaginary’ part) of a ‘vector’ (complex conjugated pointer) that is circling around the point (0;0) in the coordinate-system (here the ”Gauss’ complex number plan” (??don’t know the english word for it)) with the length of it’s amplitude (so here e.g. 32767) and the circling-frequency of the sine-frequency. So the sine-value is given by the real part of the complex number which the pointer represents.

This sounds ‘complex’ perhaps, but is easy to understand (if you know trigonometrie), just search the net a bit for more information on complex numbers and this stuff.

So finally:
When changing the frequency then just speed up the circling speed of your pointer, whose actual position is storec in a global variable, and then calculate the sine-part of it multiplied by the amplitude to get the actual samplevalue.

All this is done in my above mentioned example sinemouse.

Have fun ๐Ÿ˜€

EDIT: You can change the bufferlength using FSOUND_SetBufferSize().

  • You must to post comments
Showing 5 results
Your Answer

Please first to submit.