[alsa-devel] Play a sine wave with alsa
Luca Longhi
lucavermei at gmail.com
Thu May 10 20:05:43 CEST 2012
I've written this code to play a sine wave but I don't think it's right.
Could you tell me where I am wrong?
Especially I don't know what period_time and buffer_time are. What I
have to do to extend the playback time?
Code:
#include <alsa/asoundlib.h>
#include <math.h>
int main() {
int err;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int Fc, val;
int channels=2;
int size;
int dir=0;
unsigned int period_time= 400000;
unsigned int buffer_time= 800000;
snd_pcm_uframes_t frames;
snd_pcm_uframes_t bufferSize;
char *buffer;
/* Open PCM device for playback. */
err = snd_pcm_open(&handle, "default",SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(err));
exit(1);
}
snd_pcm_hw_params_alloca(¶ms);
err=snd_pcm_hw_params_any(handle, params);
if (err < 0) {
printf("Broken configuration for playback: no configurations
available: %s\n", snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
printf("Access type not available for playback: %s\n",
snd_strerror(err));
return err;
}
err=snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
if (err < 0) {
printf("Sample format not available for playback: %s\n",
snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_channels(handle, params, channels);
if (err < 0) {
printf("Channels count (%i) not available for playbacks: %s\n",
channels, snd_strerror(err));
return err;
}
Fc = 5000;
dir=1;
err=snd_pcm_hw_params_set_rate_near(handle, params, &Fc, &dir);
if (err < 0) {
printf("Rate %iHz not available for playback: %s\n", Fc,
snd_strerror(err));
return err;
}
dir=0;
err = snd_pcm_hw_params_set_period_time_near(handle, params,
&period_time, &dir);
if (err < 0) {
printf("Unable to set period time %i for playback:
%s\n", period_time, snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_buffer_time_near(handle, params,
&buffer_time, &dir);
if (err < 0) {
printf("Unable to set buffer time %i for playback:
%s\n", buffer_time, snd_strerror(err));
return err;
}
err = snd_pcm_hw_params(handle, params);
if (err < 0) {
printf("Unable to set hw params for playback: %s\n",
snd_strerror(err));
return err;
}
/* Use a buffer large enough to hold one period */
snd_pcm_hw_params_get_period_size(params, &frames, 0);
size = frames * 4;
short buf[size];
unsigned short ampiezza;
double frequenza = 500;
double omega; /* Pulsazione */
int x;
omega = 2 * M_PI * frequenza / 180;
ampiezza = 20000;
for (x = 0; x < size ; x++)
{
buf[x] = (short)(ampiezza * (sin (omega*x)));
}
err = snd_pcm_writei(handle, buf, frames);
if (err == -EPIPE) {
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
} else if (err < 0) {
fprintf(stderr,
"error from writei: %s\n",
snd_strerror(err));
} else if (err != (int)frames) {
fprintf(stderr,
"short write, write %d frames\n", err);
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
return 0;
}
More information about the Alsa-devel
mailing list