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; }