Skip to content

Instantly share code, notes, and snippets.

@vodik
Created November 19, 2011 06:21
Show Gist options
  • Save vodik/1378526 to your computer and use it in GitHub Desktop.
Save vodik/1378526 to your computer and use it in GitHub Desktop.
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) Simon Gomizelj, 2011
*/
#include <alsa/asoundlib.h>
static void
alsa_dump()
{
int val;
printf("ALSA library version: %s\n\n", SND_LIB_VERSION_STR);
printf("PCM stream types:\n");
for (val = 0; val < SND_PCM_STREAM_LAST; val++)
printf(" %s\n", snd_pcm_stream_name((snd_pcm_stream_t)val));
printf("PCM access types:\n");
for (val = 0; val < SND_PCM_ACCESS_LAST; val++)
printf(" %s\n", snd_pcm_access_name((snd_pcm_access_t)val));
printf("PCM formats:\n");
for (val = 0; val < SND_PCM_FORMAT_LAST; val++)
if (snd_pcm_format_name((snd_pcm_format_t)val) != NULL)
printf(" %s (%s)\n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description((snd_pcm_format_t)val));
printf("PCM states\n");
for (val = 0; val < SND_PCM_STATE_LAST; val++)
printf(" %s\n", snd_pcm_state_name((snd_pcm_state_t)val));
}
static void
alsa_pcm_dump(snd_pcm_t *handle, snd_pcm_hw_params_t *params)
{
unsigned int val, val2;
int val3;
int dir;
snd_pcm_uframes_t frames;
printf("PCM handle name = '%s'\n", snd_pcm_name(handle));
printf("PCM state = %s\n", snd_pcm_state_name(snd_pcm_state(handle)));
snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val);
printf("access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val));
snd_pcm_hw_params_get_format(params, &val3);
printf("format = '%s' (%s)\n",
snd_pcm_format_name((snd_pcm_format_t)val3),
snd_pcm_format_description((snd_pcm_format_t)val3));
snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val);
printf("subformat = '%s' (%s)\n",
snd_pcm_subformat_name((snd_pcm_subformat_t)val),
snd_pcm_subformat_description((snd_pcm_subformat_t)val));
snd_pcm_hw_params_get_channels(params, &val);
printf("channels = %d\n", val);
snd_pcm_hw_params_get_rate(params, &val, &dir);
printf("rate = %d bps\n", val);
snd_pcm_hw_params_get_period_time(params, &val, &dir);
printf("period time = %d us\n", val);
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
printf("period size = %d frames\n", (int)frames);
snd_pcm_hw_params_get_buffer_time(params, &val, &dir);
printf("buffer time = %d us\n", val);
snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val);
printf("buffer size = %d frames\n", val);
snd_pcm_hw_params_get_periods(params, &val, &dir);
printf("periods per buffer = %d frames\n", val);
snd_pcm_hw_params_get_rate_numden(params, &val, &val2);
printf("exact rate = %d/%d bps\n", val, val2);
val = snd_pcm_hw_params_get_sbits(params);
printf("significant bits = %d\n", val);
/* snd_pcm_hw_params_get_tick_time(params, &val, &dir); */
/* printf("tick time = %d us\n", val); */
val = snd_pcm_hw_params_is_batch(params);
printf("is batch = %d\n", val);
val = snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer = %d\n", val);
val = snd_pcm_hw_params_is_double(params);
printf("is double = %d\n", val);
val = snd_pcm_hw_params_is_half_duplex(params);
printf("is half duplex = %d\n", val);
val = snd_pcm_hw_params_is_joint_duplex(params);
printf("is joint duplex = %d\n", val);
val = snd_pcm_hw_params_can_overrange(params);
printf("can overrange = %d\n", val);
val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap = %d\n", val);
val = snd_pcm_hw_params_can_pause(params);
printf("can pause = %d\n", val);
val = snd_pcm_hw_params_can_resume(params);
printf("can resume = %d\n", val);
val = snd_pcm_hw_params_can_sync_start(params);
printf("can sync start = %d\n", val);
}
static void
alsa_inithw(snd_pcm_t *handle, snd_pcm_hw_params_t *params)
{
unsigned val = 44100, rc;
int dir;
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, 2);
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
perror("snd_pcm_hw_params");
exit(EXIT_FAILURE);
}
}
static void
alsa_myplay(snd_pcm_t *handle, snd_pcm_hw_params_t *params)
{
int rc;
snd_pcm_uframes_t frames;
long loops;
unsigned val;
int dir, size;
char *buffer;
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
size = frames * 4; /* 2 bytes/sample with 2 channels */
buffer = malloc(size);
snd_pcm_hw_params_get_period_time(params, &val, &dir);
loops = 5000000 / val; /* 5 seconds / period time */
while (loops > 0) {
--loops;
rc = read(0, buffer, size);
if (rc == 0) {
fprintf(stderr, "end of file on input\n");
break;
} else if (rc != size)
fprintf(stderr, "short read (%d bytes)\n", rc);
rc = snd_pcm_writei(handle, buffer, frames);
if (rc == -EPIPE) {
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
perror("snd_pcm_writei");
exit(EXIT_FAILURE);
} else if (rc != (int)frames)
fprintf(stderr, "shord write, write %d frames\n", rc);
}
snd_pcm_drain(handle);
free(buffer);
}
int
main(int argc, char *argv[])
{
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
/* alsa_dump(); */
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
perror("snd_pcm_open");
exit(EXIT_FAILURE);
}
snd_pcm_hw_params_alloca(&params);
alsa_inithw(handle, params);
alsa_myplay(handle, params);
/* alsa_pcm_dump(handle, params); */
snd_pcm_close(handle);
return 0;
}
@vodik
Copy link
Author

vodik commented Nov 19, 2011

gcc -o alsa alsa.c
./alsa < /dev/urandom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment