#include #include #include #include #include #include #include #define audio_flush(fd) audio_buffer((fd), 0, 0) #define AUDIO_DEVICE "/dev/audio" #define AUDIO_FILLSZ 4608 #define MIXER_DEVICE "/dev/mixer" #if defined(EMPEG_H_AVAILABLE) #include #else #define EMPEG_MIXER_MAGIC 'm' #define EMPEG_MIXER_WRITE_SOURCE _IOW(EMPEG_MIXER_MAGIC, 0, int) #define EMPEG_MIXER_WRITE_FLAGS _IOW(EMPEG_MIXER_MAGIC, 1, int) #define EMPEG_MIXER_SET_SAM _IOW(EMPEG_MIXER_MAGIC, 15, int) #endif static int output(int fd, void const *buf, unsigned int len) { char const *ptr = (const char *)buf; int wrote; while (len) { wrote = write(fd, ptr, len); if (wrote == -1) { if (errno == EINTR) continue; else return -1; } ptr += wrote; len -= wrote; } return 0; } static int audio_buffer(int fd, void const *buf, unsigned int len) { char const *ptr = (const char *)buf; static char hold[AUDIO_FILLSZ]; static unsigned int held; unsigned int left, grab; if (len == 0) { if (held) { memset(&hold[held], 0, &hold[AUDIO_FILLSZ] - &hold[held]); held = 0; return output(fd, hold, AUDIO_FILLSZ); } return 0; } if (held == 0 && len == AUDIO_FILLSZ) return output(fd, ptr, len); left = AUDIO_FILLSZ - held; while (len) { grab = len < left ? len : left; memcpy(&hold[held], ptr, grab); held += grab; left -= grab; ptr += grab; len -= grab; if (left == 0) { if (output(fd, hold, AUDIO_FILLSZ) == -1) return -1; held = 0; left = AUDIO_FILLSZ; } } return 0; } static int mixer_init(int fd) { int source, soft_audio_mute, mute; source = SOUND_MASK_PCM; if (ioctl(fd, EMPEG_MIXER_WRITE_SOURCE, &source) == -1) { perror("ioctl(EMPEG_MIXER_WRITE_SOURCE)"); return 3; } soft_audio_mute = 0; if (ioctl(fd, EMPEG_MIXER_SET_SAM, &soft_audio_mute) == -1) { perror("ioctl(EMPEG_MIXER_SET_SAM)"); return -1; } mute = 0; if (ioctl(fd, EMPEG_MIXER_WRITE_FLAGS, &mute) == -1) { perror("ioctl(EMPEG_MIXER_WRITE_FLAGS)"); return -1; } return 0; } int main(int argc, char *argv[]) { static char buffer[AUDIO_FILLSZ]; int audio_fd, mixer_fd; unsigned int len; if ((audio_fd = open(AUDIO_DEVICE, O_WRONLY)) == -1) { perror(AUDIO_DEVICE); return 1; } if ((mixer_fd = open(MIXER_DEVICE, O_WRONLY)) == -1) { perror(MIXER_DEVICE); return 1; } if (mixer_init(mixer_fd) == -1) { close(audio_fd); close(mixer_fd); return 2; } while ((len = fread(buffer, 4, AUDIO_FILLSZ / 4, stdin))) { if (audio_buffer(audio_fd, buffer, 4 * len) == -1) { perror("write"); return 3; } } if (ferror(stdin)) { perror("read"); return 4; } if (audio_flush(audio_fd) == -1) { perror("write"); return 3; } if (close(audio_fd) == -1) { perror("close"); return 5; } return 0; }