Skip to content

Instantly share code, notes, and snippets.

@mchalain

mchalain/player.c

Created Apr 6, 2020
Embed
What would you like to do?
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
You can’t perform that action at this time.