X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=play.c;h=1a30285d1e9e8658f961e5c2e539b94409d1973c;hb=c73c5df5f53e464a57852399771707cc923a497a;hp=fd8c9b28a8deed548be8e2344ca909c131dbf9b4;hpb=d7cda933daa35663b2b9b61d62cb514afa37fd18;p=paraslash.git diff --git a/play.c b/play.c index fd8c9b28..1a30285d 100644 --- a/play.c +++ b/play.c @@ -61,13 +61,13 @@ do { if (EXP) \ 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; -void para_log(__unused int ll, const char* fmt,...) +void para_log(__a_unused int ll, const char* fmt,...) { va_list argp; @@ -94,11 +94,11 @@ static void read_wav_header(void) } /* - * 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; @@ -106,6 +106,18 @@ static void set_alsa_params(void) 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); @@ -159,15 +171,16 @@ static void set_alsa_params(void) 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 + * \param nbytes number of bytes (not 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 nbytes) { + size_t count = nbytes / bytes_per_frame; snd_pcm_sframes_t r, result = 0; while (count > 0) { /* write interleaved frames */ @@ -186,7 +199,14 @@ static snd_pcm_sframes_t pcm_write(u_char *data, size_t count) 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(); } /* @@ -239,7 +259,7 @@ static void play_pcm(size_t loaded) 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); @@ -257,13 +277,13 @@ again: } p = audiobuf; while (loaded >= chunk_bytes) { - ret = pcm_write(p, chunk_size) * bytes_per_frame; + ret = alsa_write(p, chunk_bytes); p += ret; written += ret; loaded -= ret; } if (loaded && p != audiobuf) - memcpy(audiobuf, p, loaded); + memmove(audiobuf, p, loaded); read: ret = read(STDIN_FILENO, audiobuf + loaded, bufsize - loaded); if (ret < 0) @@ -272,7 +292,7 @@ read: loaded += ret; goto again; } - snd_pcm_drain(handle); + alsa_shutdown(); } /* @@ -293,10 +313,7 @@ static size_t check_wave(void) 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) { @@ -305,21 +322,9 @@ int main(int argc, char *argv[]) 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; }