$NetBSD: patch-ag,v 1.1.1.1 2006/01/24 04:00:37 xtraeme Exp $ --- libavformat/audio.c.orig 2004-06-19 05:59:34.000000000 +0200 +++ libavformat/audio.c @@ -18,10 +18,19 @@ */ #include "avformat.h" +#ifdef __NetBSD__ +#define USE_SUNAUDIO +#endif + #include #include #include +#ifndef USE_SUNAUDIO #include +#else +#include +#include +#endif #include #include #include @@ -47,9 +56,18 @@ static int audio_open(AudioData *s, int int tmp, err; char *flip = getenv("AUDIO_FLIP_LEFT"); +#ifdef USE_SUNAUDIO + audio_info_t info; + struct audio_prinfo *settings; + int mixer_fd; + + if (!audio_device) + audio_device = "/dev/audio"; +#else /* open linux audio device */ if (!audio_device) audio_device = "/dev/dsp"; +#endif if (is_output) audio_fd = open(audio_device, O_WRONLY); @@ -77,6 +95,7 @@ static int audio_open(AudioData *s, int } #endif +#ifndef USE_SUNAUDIO /* select format : favour native format */ err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); @@ -124,14 +143,114 @@ static int audio_open(AudioData *s, int } if (tmp) s->channels = 2; +#else /* USE_SUNAUDIO */ + AUDIO_INITINFO(&info); + if (!is_output) { + info.mode = AUMODE_RECORD; + settings = &info.record; + } else { + info.mode = AUMODE_PLAY; + settings = &info.play; + } + + /* select format */ + /* Try native 16 bit format first */ +#ifdef WORDS_BIGENDIAN + settings->encoding = AUDIO_ENCODING_SLINEAR_BE; + s->codec_id = CODEC_ID_PCM_S16BE; +#else + settings->encoding = AUDIO_ENCODING_SLINEAR_LE; + s->codec_id = CODEC_ID_PCM_S16LE; +#endif + settings->precision = 16; + err = ioctl(audio_fd, AUDIO_SETINFO, &info); + if (err < 0) { + fprintf(stderr, "Soundcard does not support signed 16 bit sample format\n"); + close(audio_fd); + return -EIO; + } + /* set channels */ + AUDIO_INITINFO(&info); + settings->channels = s->channels; + err = ioctl(audio_fd, AUDIO_SETINFO, &info); + if (err < 0) { + fprintf(stderr, "stereo not supported, using mono"); + } + + /* set gain */ + AUDIO_INITINFO(&info); + settings->gain = AUDIO_MAX_GAIN; + err = ioctl(audio_fd, AUDIO_SETINFO, &info); + if (err < 0) { + fprintf(stderr, "setting gain to %d failed", AUDIO_MAX_GAIN); + } + +#ifndef MIXER_DEVICE +#define MIXER_DEVICE "/dev/mixer" +#endif + if ((mixer_fd=open(MIXER_DEVICE, O_RDONLY)) == -1) + fprintf(stderr, "can't open %s\n", MIXER_DEVICE); + else { + int n; + mixer_devinfo_t mdt; + /* get debuggin information about all mixer devices */ + mdt.index = n = 0; + while (ioctl(mixer_fd, AUDIO_MIXER_DEVINFO, &mdt) != -1) { + if (strcasecmp(mdt.label.name, "inputs") == 0) { + while (mdt.next != -1) { + printf("Mixer device %d: `%s' has type %d, class %d\n", + mdt.index, mdt.label.name, mdt.type, + mdt.mixer_class); + mdt.index = mdt.next; + if (ioctl(mixer_fd, AUDIO_MIXER_DEVINFO, &mdt) == -1) { + fprintf(stderr, "getting next mixer device " + "failed (%d)", mdt.index); + break; + } + printf("next device: "); + } + printf("Mixer device %d: `%s' has type %d, class %d\n", + mdt.index, mdt.label.name, mdt.type, + mdt.mixer_class); + } + n++; + mdt.index = n; + } + /* set input to line-in */ + AUDIO_INITINFO(&info); + settings->port = AUDIO_LINE_IN; + err = ioctl(audio_fd, AUDIO_SETINFO, &info); + if (err < 0) { + fprintf(stderr, "setting input to line-in failed"); + } + } + close(mixer_fd); +#endif + +#ifndef USE_SUNAUDIO tmp = s->sample_rate; err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); if (err < 0) { perror("SNDCTL_DSP_SPEED"); goto fail; } + s->sample_rate = tmp; /* store real sample rate */ +#else + AUDIO_INITINFO(&info); + settings->sample_rate = s->sample_rate; + err = ioctl(audio_fd, AUDIO_SETINFO, &info); + if (err < 0) { + fprintf(stderr, "setting sample rate to %d failed", s->sample_rate); + err = ioctl(audio_fd, AUDIO_GETINFO, &info); + if (err < 0) { + perror("AUDIO_GETINFO"); + goto fail; + } + s->sample_rate = settings->sample_rate; + } +#endif s->fd = audio_fd; return 0; @@ -240,7 +359,11 @@ static int audio_read_packet(AVFormatCon AudioData *s = s1->priv_data; int ret, bdelay; int64_t cur_time; +#ifndef USE_SUNAUDIO struct audio_buf_info abufi; +#else + audio_info_t info; +#endif if (av_new_packet(pkt, s->frame_size) < 0) return AVERROR_IO; @@ -276,9 +399,15 @@ static int audio_read_packet(AVFormatCon /* compute pts of the start of the packet */ cur_time = av_gettime(); bdelay = ret; +#ifndef USE_SUNAUDIO if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { bdelay += abufi.bytes; } +#else + if (ioctl(s->fd, AUDIO_GETINFO, &info) == 0) { + bdelay += info.record.seek * (info.record.precision/8); + } +#endif /* substract time represented by the number of bytes in the audio fifo */ cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);