1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
$NetBSD: patch-ag,v 1.2 2006/02/16 10:26:30 abs 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
+#ifndef USE_SUNAUDIO
#include <sys/soundcard.h>
+#else
+#include <sys/types.h>
+#include <sys/audioio.h>
+#endif
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
@@ -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);
|