DemoPublic/Linux/Application/ALSA/SndPam/SndPam.c

169 lines
5.2 KiB
C

/**
* @file SndPam.c
* @author Rick Chan (cy187lion@sina.com)
* @brief
* @version 0.1
* @date 2020-04-08
*
* @copyright Copyright (c) 2020
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <pthread.h>
#define PERIOD_CNT 16
#define PERIOD_FRAMES 512
#define PERIOD_BYTES 2048
#define BUF_SZ (PERIOD_CNT * PERIOD_FRAMES)
#define TOTAL_BUF (PERIOD_CNT * PERIOD_BYTES)
void init_pcm(snd_pcm_t *handle, unsigned int rate, unsigned int ch, unsigned int frames, unsigned int periods)
{
int err;
snd_pcm_hw_params_t *hw_params;
// snd_pcm_sw_params_t *sw_params;
snd_pcm_uframes_t period_size = frames;
snd_pcm_uframes_t buffer_size = periods*frames;
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
printf ("cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) {
printf ("cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
printf ("cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_format (handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
printf ("cannot set sample format (%s)\n",
snd_strerror (err));
// exit (1);
}
if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &rate, 0)) < 0) {
printf ("cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_periods_near(handle, hw_params, &periods, NULL)) < 0) {
printf ("cannot set periods (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_period_size_near(handle, hw_params, &period_size, NULL)) < 0) {
printf ("cannot set period size (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_buffer_size_near(handle, hw_params, &buffer_size)) < 0) {
printf ("cannot set buffer size (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, 2)) < 0) {
printf ("cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
printf ("cannot set hardware parameters (%s)\n",
snd_strerror (err));
exit (1);
}
/*snd_pcm_sw_params_alloca (&sw_params);
if ((err = snd_pcm_sw_params_current(handle, sw_params)) < 0) {
printf ("cannot get current software parameters (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, 0)) < 0) {
printf ("cannot set threshold (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) {
printf ("cannot set software parameters (%s)\n",
snd_strerror (err));
exit (1);
}*/
if ((err = snd_pcm_prepare (handle)) < 0) {
printf ("cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
exit (1);
}
}
snd_pcm_t* init_playback(char output[], unsigned int rate, unsigned int ch, unsigned int frames, unsigned int periods)
{
int err;
snd_pcm_t *playback_handle;
if ((err = snd_pcm_open (&playback_handle, output, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
printf ("cannot open audio device %s (%s)\n",
output,
snd_strerror (err));
exit (1);
}
init_pcm(playback_handle, rate, ch, frames, periods);
return playback_handle;
}
#if 0
snd_pcm_t* init_capture(char input[])
{
int err;
snd_pcm_t *capture_handle;
if ((err = snd_pcm_open (&capture_handle, input, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
printf ("cannot open audio device %s (%s)\n",
input,
snd_strerror (err));
exit (1);
}
init_pcm(capture_handle);
return capture_handle;
}
#endif
int main (int argc, char *argv[])
{
snd_pcm_t* playback_handle;
unsigned int rate;
unsigned int ch;
unsigned int frames;
unsigned int periods;
if (2==argc) {
if (0==strcmp("-v", argv[1]))
printf ("SndPam Version 1.0\r\n");
if (0==strcmp("-h", argv[1]))
printf ("SndPam <device>\r\nExp: SndPam plughw:0,0 <rate> <ch> <frames> <periods>\r\n");
exit (0);
}
if (6!=argc) {
printf ("SndPam <device>\r\nExp: SndPam plughw:0,0 <rate> <ch> <frames> <periods>\r\n");
exit (0);
}
sscanf(argv[2], "%u", &rate);
sscanf(argv[3], "%u", &ch);
sscanf(argv[4], "%u", &frames);
sscanf(argv[5], "%u", &periods);
printf("Open With R=%u, CH=%u, Frames=%u, Periods=%u.\r\n", rate, ch, frames, periods);
playback_handle = init_playback (argv[1], rate, ch, frames, periods);
exit (0);
}