Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

dos-like

Engine for making things with a MS-DOS feel, but for modern platforms · By Mattias Gustavsson

How to Generate Random Beeps (Square Waves)? (I am getting only noise).

A topic by Vitor Almeida created 11 days ago Views: 34 Replies: 4
Viewing posts 1 to 4
(1 edit)

Hi everyone, how are you?

I am trying to do sound manipulation by generating a beep (square wave) simulating a PC speaker with a certain frequency and amplitude.

Initially, I'll make the beep for a Pong game when the ball hits a surface.

I read the library's source code and looked for some YouTube videos to understand the audio concepts involved.

But the most I'm managing to do is generate noise for a short time.

Currently I have a variable where I create the sound dynamically (before playing):


    struct sound_t* sound_border;


I initialize the sound system with the code:


    setsoundmode(soundmode_8bit_mono_11025);


I create the sound with the code:


    int channels = 1;
    int samplerate = 11025l;
    short samples[] = { 0 };
    sound_border = createsound(channels, samplerate, 8, samples); // 8 = framecount


And then when it's necessary to play:


    playsound(1, sound_score, 0, 255); // full volume, no loop, channel 1

However, I still don't understand the concept of "framecount" (is it the number of times the samples will be copied into the sound buffer for each channel?).

I don't understand how nois is being played if my sample rate is zero (and the noise changes when I change the framecount).

Any tips would be very helpful.

Thank you everyone.

Developer

Try something like this:

#include <math.h>
#include <stdlib.h>
#include "dos.h"
int main(int argc, char *argv[]) {
    short samples[ 22050 ]; // at 11025hz sample rate, we need 22050 samples for two seconds
    float tonefreq = 440.0; // 440hz sine wave tone (note A4)
    for( int i = 0; i < 22050; ++i) { // two seconds
        float s = sinf( i * 2.0f * 3.14159f * tonefreq / 11025.0f ); // 11025hz sample rate
        samples[ i ] = (short)( s * 32000.0f ); // convert from -1 to 1 range
    }
    
    struct sound_t* beep = createsound( 1 /* mono */, 11025, 22050, samples );
    playsound( 1, beep, 0 /* no looping */, 127 /* half volume */ );
    while(!shuttingdown()) {
        waitvbl();     
        if( keystate( KEY_ESCAPE ) ) {
            break;
        }
    }
    return 0;
}

The `framecount` is a bit of a weird term in audio. depending on how many channels you are playing, a single sample can have 1 value (for mono) or 2 values (for stereo) or even more for things like 5.1 sound (but not supported by dos-like). a "frame" in this context, is simply 1 sample for mono or 2 samples for stereo. so in the case above, where I have 22050 mono samples, i pass the samples buffer and a framecount of 22050. If i decided to do stereo, i would have a samples buffer of  44100, but still pass a framecount of 22050 (but i will pass a channel count of 2 so the createsound function knows that the samples buffer contains framecount*2 values)

Developer

Also, if you don't want to create sounds on your own, you can play any of the sound defined in General Midi (128 different instrument sounds including a few sound effects) with soundblaster 16 emulation using something like this:

#include <stdlib.h>
#include "dos.h"
int main(int argc, char *argv[]) {
    setinstrument( 1, 14 );
    setsoundbank( DEFAULT_SOUNDBANK_SB16 );
    int exit = 0;
    while( !exit ) {
        noteon( 1, 52, 127 );
        for( int i = 0; i < 40; ++i ) {
            waitvbl();     
            if( keystate( KEY_ESCAPE ) || shuttingdown() ) {
                exit = 1;
                break;
            }
        }
        noteoff( 1, 52 );
        for( int i = 0; i < 80; ++i ) {
            waitvbl();     
            if( keystate( KEY_ESCAPE )  || shuttingdown() ) {
                exit = 1;
                break;
            }
        }
    }
    return 0;
}

Mattias, thank you so much: you gave me all the tools I need to study more and understand the sound generation process.

The code you provided worked. I'm also using this video series (https://www.youtube.com/watch?v=tgamhuQnOkM) by javidx9 to practically understand the formula used in oscillator generation (to create a square wave, for example), but you've already tied up all the loose ends I needed to use a buffer and generate sound with control (amplitude, frequency, type, etc.).

Thank you for your help and precious time, my friend (I am really a beginner in sound synthesis, learning as I go).

Regarding the project, you've already helped me a lot (all the questions I had have been answered; now it's just a matter of understanding and programming).

Thank you and if you need help in your projects (promotion, testing etc.) I am available.

Developer

No worries, I'm glad I could help :) and if you get stuck on anything else, don't hesitate to ask!