while (0)
static snd_pcm_t *handle;
-static unsigned char *audiobuf;
static snd_pcm_uframes_t chunk_size;
+static unsigned char *audiobuf;
static size_t bytes_per_frame;
static struct timeval *start_time;
static struct gengetopt_args_info conf;
}
/*
- * set_alsa_params - Prepare the PCM handle for writing
+ * open and prepare the PCM handle for writing
*
* Install PCM software and hardware configuration. Exit on errors.
*/
-static void set_alsa_params(void)
+static void alsa_init(void)
{
snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;
stop_threshold;
unsigned buffer_time = 0;
int err;
+ snd_pcm_info_t *info;
+ snd_output_t *log;
+
+ snd_pcm_info_alloca(&info);
+ if (snd_output_stdio_attach(&log, stderr, 0) < 0)
+ EXIT(E_LOG);
+ err = snd_pcm_open(&handle, conf.device_arg,
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if (err < 0)
+ EXIT(E_PCM_OPEN);
+ if ((err = snd_pcm_info(handle, info)) < 0)
+ EXIT(E_SND_PCM_INFO);
snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_sw_params_alloca(&swparams);
bytes_per_frame = snd_pcm_format_physical_width(FORMAT) * conf.channels_arg / 8;
}
-/*
- * pcm_write - push out pcm frames
+/**
+ * push out pcm frames
* \param data pointer do data to be written
* \param count number of frames
*
* \return Number of bytes written. Exit on errors.
*/
-static snd_pcm_sframes_t pcm_write(u_char *data, size_t count)
+int alsa_write(u_char *data, size_t count)
{
snd_pcm_sframes_t r, result = 0;
while (count > 0) {
data += r * bytes_per_frame;
}
}
- return result;
+ return result * bytes_per_frame;
+}
+
+void alsa_shutdown(void)
+{
+ snd_pcm_drain(handle);
+ snd_pcm_close(handle);
+ snd_config_update_free_global();
}
/*
unsigned char *p;
struct timeval delay;
- set_alsa_params();
+ alsa_init();
chunk_bytes = chunk_size * bytes_per_frame;
bufsize = (conf.bufsize_arg * 1024 / chunk_bytes) * chunk_bytes;
audiobuf = realloc(audiobuf, bufsize);
}
p = audiobuf;
while (loaded >= chunk_bytes) {
- ret = pcm_write(p, chunk_size) * bytes_per_frame;
+ ret = alsa_write(p, chunk_size);
p += ret;
written += ret;
loaded -= ret;
loaded += ret;
goto again;
}
- snd_pcm_drain(handle);
+ alsa_shutdown();
}
/*
int main(int argc, char *argv[])
{
- snd_pcm_info_t *info;
- snd_output_t *log;
struct timeval tv;
- int err;
cmdline_parser(argc, argv, &conf);
if (conf.start_time_given) {
EXIT(E_SYNTAX);
start_time = &tv;
}
- snd_pcm_info_alloca(&info);
- if (snd_output_stdio_attach(&log, stderr, 0) < 0)
- EXIT(E_LOG);
- err = snd_pcm_open(&handle, conf.device_arg,
- SND_PCM_STREAM_PLAYBACK, 0);
- if (err < 0)
- EXIT(E_PCM_OPEN);
- if ((err = snd_pcm_info(handle, info)) < 0)
- EXIT(E_SND_PCM_INFO);
audiobuf = malloc(WAV_HEADER_LEN);
read_wav_header();
play_pcm(check_wave());
- snd_pcm_close(handle);
free(audiobuf);
-// snd_output_close(log);
- snd_config_update_free_global();
return EXIT_SUCCESS;
}