1 /*
2 * SID_hp.i - 6581 emulation, HP-UX specific stuff
3 *
4 * Lutz Vieweg <lkv@mania.robin.de>
5 */
6
7 extern "C" {
8 #include <sys/audio.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 }
13
14 #define TXBUFSIZE 16384 // bytes, not samples
15 #define TXFRAGSIZE 1024 // samples, not bytes
16 #define TXLOWWATER (TXBUFSIZE-(TXFRAGSIZE*2)) // bytes, not samples
17
18 /*
19 * Initialization
20 */
21
init_sound(void)22 void DigitalRenderer::init_sound(void)
23 {
24 ready = false;
25
26 if ((fd = open("/dev/audio", O_WRONLY | O_NDELAY, 0)) < 0) {
27 fprintf(stderr, "unable to open /dev/audio -> no sound\n");
28 return;
29 }
30
31 int flags;
32 if ((flags = fcntl (fd, F_GETFL, 0)) < 0) {
33 fprintf(stderr, "unable to set non-blocking mode for /dev/audio -> no sound\n");
34 return;
35 }
36 flags |= O_NDELAY;
37 if (fcntl (fd, F_SETFL, flags) < 0) {
38 fprintf(stderr, "unable to set non-blocking mode for /dev/audio -> no sound\n");
39 return;
40 }
41
42 if (ioctl(fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) {
43 fprintf(stderr, "unable to select 16bit-linear sample format -> no sound\n");
44 return;
45 }
46
47 if (ioctl(fd, AUDIO_SET_SAMPLE_RATE, 44100)) {
48 fprintf(stderr, "unable to select 44.1kHz sample-rate -> no sound\n");
49 return;
50 }
51
52 if (ioctl(fd, AUDIO_SET_CHANNELS, 1)) {
53 fprintf(stderr, "unable to select 1-channel playback -> no sound\n");
54 return;
55 }
56
57 // choose between:
58 // AUDIO_OUT_SPEAKER
59 // AUDIO_OUT_HEADPHONE
60 // AUDIO_OUT_LINE
61 if (ioctl(fd, AUDIO_SET_OUTPUT, AUDIO_OUT_SPEAKER)) {
62 fprintf(stderr, "unable to select audio output -> no sound\n");
63 return;
64 }
65
66 {
67 // set volume:
68 audio_describe description;
69 audio_gains gains;
70 if (ioctl(fd, AUDIO_DESCRIBE, &description)) {
71 fprintf(stderr, "unable to get audio description -> no sound\n");
72 return;
73 }
74 if (ioctl (fd, AUDIO_GET_GAINS, &gains)) {
75 fprintf(stderr, "unable to get gain values -> no sound\n");
76 return;
77 }
78
79 float volume = 1.0;
80 gains.transmit_gain = (int)((float)description.min_transmit_gain +
81 (float)(description.max_transmit_gain
82 - description.min_transmit_gain)
83 * volume);
84 if (ioctl (fd, AUDIO_SET_GAINS, &gains)) {
85 fprintf(stderr, "unable to set gain values -> no sound\n");
86 return;
87 }
88 }
89
90 if (ioctl(fd, AUDIO_SET_TXBUFSIZE, TXBUFSIZE)) {
91 fprintf(stderr, "unable to set transmission buffer size -> no sound\n");
92 return;
93 }
94
95 sound_calc_buf = new int16[TXFRAGSIZE];
96
97 linecnt = 0;
98
99 ready = true;
100 return;
101 }
102
103
104 /*
105 * Destructor
106 */
107
~DigitalRenderer()108 DigitalRenderer::~DigitalRenderer()
109 {
110 if (fd > 0) {
111 if (ready) {
112 ioctl(fd, AUDIO_DRAIN);
113 }
114 ioctl(fd, AUDIO_RESET);
115 close(fd);
116 }
117 }
118
119
120 /*
121 * Pause sound output
122 */
123
Pause(void)124 void DigitalRenderer::Pause(void)
125 {
126 }
127
128
129 /*
130 * Resume sound output
131 */
132
Resume(void)133 void DigitalRenderer::Resume(void)
134 {
135 }
136
137
138 /*
139 * Fill buffer, sample volume (for sampled voice)
140 */
141
EmulateLine(void)142 void DigitalRenderer::EmulateLine(void)
143 {
144 sample_buf[sample_in_ptr] = volume;
145 sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
146
147 // testing the audio status at each raster-line is
148 // really not necessary. Let's do it every 50th one..
149 // ought to be enough by far.
150
151 linecnt--;
152 if (linecnt < 0 && ready) {
153 linecnt = 50;
154
155 // check whether we should add some more data to the
156 // transmission buffer.
157
158 if (ioctl(fd, AUDIO_GET_STATUS, &status)) {
159 fprintf(stderr,"fatal: unable to get audio status\n");
160 exit(20);
161 }
162
163 if (status.transmit_buffer_count < TXLOWWATER) {
164 // add one sound fragment..
165 calc_buffer(sound_calc_buf, TXFRAGSIZE*2);
166
167 // since we've checked for enough space in the transmission buffer,
168 // it is an error if the non-blocking write returns anything but
169 // TXFRAGSIZE*2
170 if (TXFRAGSIZE*2 != write (fd, sound_calc_buf, TXFRAGSIZE*2)) {
171 fprintf(stderr,"fatal: write to audio-device failed\n");
172 exit(20);
173 }
174 }
175 }
176 }
177
178