#ifndef lint static char rcsid[] = "$Id: encode_sun.c,v 1.3 1997/03/25 15:21:27 tommy Exp $"; #endif #include #include #include #include #include #include #include #include #include "play.h" #include "encode_sun.h" sun_header_t *check_sunaudio(char *audio_file) { int fd; static sun_header_t header; if ((fd = open(audio_file, O_RDONLY)) < 0) { warn("%s", audio_file); return (sun_header_t*)FAIL; } if (read(fd, &header, SUNAUDIO_HDR_SIZE) < 0) { warn("%s", audio_file); return NULL; } header.magic = htonl(header.magic); if (header.magic != SUNAUDIO_MAGIC) return NULL; header.head_length = htonl(header.head_length); if (header.head_length > SUNAUDIO_HDR_SIZE) { size_t infosize = header.head_length - SUNAUDIO_HDR_SIZE; if ((header.infop = malloc(infosize)) == NULL) { warn("%s", "malloc"); return (sun_header_t*)FAIL; } if (read(fd, header.infop, infosize) < 0) { warn("%s", audio_file); return (sun_header_t*)FAIL; } } else { header.infop = NULL; } close(fd); header.head_length = header.head_length; header.data_length = htonl(header.data_length); header.data_format = htonl(header.data_format); header.sample_rate = htonl(header.sample_rate); header.channels = htonl(header.channels); switch (header.data_format) { case SUNAUDIO_ENCODING_MULAW_8: header.data_format = AFMT_MU_LAW; break; case SUNAUDIO_ENCODING_LINEAR_8: case SUNAUDIO_ENCODING_LINEAR_16: case SUNAUDIO_ENCODING_LINEAR_24: case SUNAUDIO_ENCODING_LINEAR_32: header.data_format = AFMT_S16_LE; break; case SUNAUDIO_ENCODING_FLOAT: case SUNAUDIO_ENCODING_DOUBLE: header.data_format = AFMT_MU_LAW; break; default: warn("%s: Unknown format", header.data_format); return (sun_header_t*)FAIL; } return &header; } void print_sun_header(sun_header_t *headp) { printf(" magic = %d\n", headp->magic); printf("headerlength = %d\n", headp->head_length); printf(" data_length = %d\n", headp->data_length); printf(" data_format = %d\n", headp->data_format); printf(" sample_rate = %d\n", headp->sample_rate); printf(" channels = %d\n", headp->channels); if (headp->infop != NULL) printf(" info = %s\n", headp->infop); } int play_sunaudio(char *audio_file, sun_header_t *headp, arg_params_t *params) { unsigned char *bufp; int stat; int devfd, filefd; char *device; if (f_extra) print_sun_header(headp); if (params->device == NULL) device = DEV_DSP; else device = params->device; if (headp->infop != NULL) free(headp->infop); if (headp->data_length == SUNAUDIO_UNKNOWN_SIZE) headp->data_length = 4096; if ((devfd = open(device, O_WRONLY)) < 0) err(1, "%s", device); if (f_hasdsp && ioctl(devfd, SNDCTL_DSP_SETFMT, &headp->data_format) < 0) { warn("%s", device); stat = FAIL; goto failplay0; } if ((filefd = open(audio_file, O_RDONLY)) < 0) { warn("%s", audio_file); stat = FAIL; goto failplay0; } if ((bufp = (char*)malloc(headp->data_length)) == NULL) { warn("%s", "malloc"); stat = FAIL; goto failplay1; } intr = FALSE; signal(SIGINT, intr_play); if ((stat = read(filefd, bufp, headp->head_length)) < 0) { warn("%s", audio_file); goto failplay2; } if (!intr && (stat = read(filefd, bufp, headp->data_length)) < 0) { warn("%s", audio_file); goto failplay2; } if (!intr && (stat = write(devfd, bufp, stat)) < 0) { warn("%s", audio_file); goto failplay2; } failplay2: free(bufp); failplay1: close(filefd); failplay0: close(devfd); return stat; }