Simple noise generator
#include <alsa/asoundlib.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <sched.h> | |
snd_pcm_t *player_init(char *soundcard, int nbsamples) | |
{ | |
int ret; | |
snd_pcm_t *playback_handle; | |
snd_pcm_open(&playback_handle, soundcard, SND_PCM_STREAM_PLAYBACK, 0); | |
snd_pcm_hw_params_t *hw_params; | |
snd_pcm_hw_params_malloc(&hw_params); | |
snd_pcm_hw_params_any(playback_handle, hw_params); | |
int channels = 2; | |
snd_pcm_hw_params_set_channels(playback_handle, hw_params, channels); | |
snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | |
snd_pcm_format_t pcm_format = SND_PCM_FORMAT_S16_LE; | |
snd_pcm_hw_params_set_format(playback_handle, hw_params, pcm_format); | |
unsigned int rate = 44100; | |
snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &rate, NULL); | |
int periods = 3; | |
ret = snd_pcm_hw_params_set_periods(playback_handle, hw_params, periods, 0); | |
if (ret != 0) | |
printf("set_periods error %s\n", snd_strerror(ret)); | |
ret = snd_pcm_hw_params_set_period_size(playback_handle, hw_params, nbsamples, 0); | |
if (ret != 0) | |
printf("set_period_size error %s\n", snd_strerror(ret)); | |
ret = snd_pcm_hw_params_set_buffer_size(playback_handle, hw_params, nbsamples * periods); | |
if (ret != 0) | |
printf("set_buffer_size error %s\n", snd_strerror(ret)); | |
snd_pcm_hw_params(playback_handle, hw_params); | |
snd_pcm_uframes_t buffersize = 0; | |
snd_pcm_hw_params_get_buffer_size(hw_params, &buffersize); | |
snd_pcm_uframes_t periodsize = 0; | |
snd_pcm_hw_params_get_period_size(hw_params, &periodsize, 0); | |
snd_pcm_hw_params_get_periods(hw_params, &periods, 0); | |
printf("buffersize %ld, periodsize %ld, nb periods %d\n", buffersize, periodsize, periods); | |
snd_pcm_prepare(playback_handle); | |
snd_pcm_hw_params_free(hw_params); | |
return playback_handle; | |
} | |
int generator_init(void) | |
{ | |
unsigned int seed; | |
int fd = open("/dev/random", R_OK); | |
sched_yield(); | |
read(fd, &seed, sizeof(seed)); | |
close(fd); | |
srandom(seed); | |
} | |
void generator(int16_t *samples, int nbsamples, int16_t max) | |
{ | |
int i; | |
for (i = 0; i < nbsamples; i++) | |
{ | |
int16_t *left = &samples[i * 2]; | |
int16_t *right = &samples[i * 2 + 1]; | |
*left = random() * max / RAND_MAX; | |
*right = random() * max / RAND_MAX; | |
} | |
} | |
typedef void (*generator_t)(int16_t *samples, int nbsamples, int16_t max); | |
int player_run(snd_pcm_t *playback_handle, int nbsamples, generator_t generator) | |
{ | |
int run = 1; | |
int16_t *buffer = malloc(nbsamples * sizeof(int16_t) * 2); | |
generator_init(); | |
while (run) | |
{ | |
generator(buffer, nbsamples, INT16_MAX); | |
snd_pcm_writei(playback_handle, buffer, nbsamples); | |
} | |
free(buffer); | |
} | |
void player_finish(snd_pcm_t *handle) | |
{ | |
snd_pcm_drain(handle); | |
snd_pcm_close(handle); | |
} | |
int main(int argc, char **argv) | |
{ | |
snd_pcm_t *handle = player_init("default", 1024); | |
generator_init(); | |
player_run(handle, 1024, &generator); | |
player_finish(handle); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment