0
101 Jul 19, 2011 at 19:11

Hi,
I am new to openAL. I wanted to generate a wave with user parameters using openAL. i.e. according to the parameters input, a certain wave will be produced. The code I wrote is below. I am unable however, to get a sine wave at the parameters that should be producing a sine wave. So i feel that there is a problem with my code.. Any help would be greatly appreciated. Thank you.

        #include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <math.h>

main (int argc, char *argv[])
{
int i;
int err;
int t;
int buf[128];
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;

if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
argv[1],
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S32_LE)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (1);
}

int rate = 96000;
if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, 0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}

if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (1);
}

snd_pcm_hw_params_free (hw_params);

if ((err = snd_pcm_prepare (playback_handle)) < 0) {
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
exit (1);
}

for (t=0; t<128; t++ ) {
buf[t] = 0.000001 * sin( 2 * 3.14159 *11 / 128 * t ) ;
}
while( 1 ) {
if ((err = snd_pcm_writei (playback_handle, buf, 128)) != 128) {
fprintf (stderr, "write to audio interface failed (%s)\n",
snd_strerror (err));
exit (1);
}
}

snd_pcm_close (playback_handle);
exit (0);
}


#### 2 Replies

0
139 Jul 19, 2011 at 20:02

Please use …[/code[b][/b]] tags when posting code on the forum, to preserve the formatting. As for your problem, your sine-generating code looks wrong. It’s a buffer of integers, but you’re multiplying by 0.000001, so everything will be rounded to zero. With S32 amplitudes the range is +/- 2 billion and change. Try multiplying the sine by 100 million or 1 billion and you should be able to hear something. [code]…[/code**] tags when posting code on the forum, to preserve the formatting.

As for your problem, your sine-generating code looks wrong. It’s a buffer of integers, but you’re multiplying by 0.000001, so everything will be rounded to zero. With S32 amplitudes the range is +/- 2 billion and change. Try multiplying the sine by 100 million or 1 billion and you should be able to hear something.

0
152 Jul 19, 2011 at 21:38

My OpenAL version could be a bit old, but my version only supports up to 16bit streams. Either way, when you call alBufferData(…), make sure you supply the correct audio format, which is 32bit in your case (and assuming that’s supported). I’m also only familiar with 32bit floating point buffers for audio data in other APIs. I’ve never seen integer based ones. If OpenAL allows it though, it should be fine as long as you properly map your floating point sin wav to an integer.

As Reed said, you’re buffer assignment is a little off. Your amplitude (0.000001) is way to low. For a 32bit floating point audio stream, you want your sin wave to oscillate between 1.0 and -1.0 for full loudness. For the time being, set your amplitude to 1.0. Secondly, your bit stream is using an int data type, so you want to map your floating point value back into an integer. You need to multiply your sin wave, which should be in the range -1.0 to 1.0, by 2\^31.