ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/SID_hp.h
Revision: 1.3
Committed: 2004-01-12T15:13:20Z (19 years, 1 month ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * SID_hp.h - 6581 emulation, HP-UX specific stuff
3     *
4 cebix 1.3 * Frodo (C) 1994-1997,2002-2004 Christian Bauer
5 cebix 1.1 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     extern "C" {
22     #include <sys/audio.h>
23     #include <unistd.h>
24     #include <fcntl.h>
25     #include <sys/ioctl.h>
26     }
27    
28     #define TXBUFSIZE 16384 // bytes, not samples
29     #define TXFRAGSIZE 1024 // samples, not bytes
30     #define TXLOWWATER (TXBUFSIZE-(TXFRAGSIZE*2)) // bytes, not samples
31    
32     /*
33     * Initialization
34     */
35    
36     void DigitalRenderer::init_sound(void)
37     {
38     ready = false;
39    
40     if ((fd = open("/dev/audio", O_WRONLY | O_NDELAY, 0)) < 0) {
41     fprintf(stderr, "unable to open /dev/audio -> no sound\n");
42     return;
43     }
44    
45     int flags;
46     if ((flags = fcntl (fd, F_GETFL, 0)) < 0) {
47     fprintf(stderr, "unable to set non-blocking mode for /dev/audio -> no sound\n");
48     return;
49     }
50     flags |= O_NDELAY;
51     if (fcntl (fd, F_SETFL, flags) < 0) {
52     fprintf(stderr, "unable to set non-blocking mode for /dev/audio -> no sound\n");
53     return;
54     }
55    
56     if (ioctl(fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) {
57     fprintf(stderr, "unable to select 16bit-linear sample format -> no sound\n");
58     return;
59     }
60    
61     if (ioctl(fd, AUDIO_SET_SAMPLE_RATE, 44100)) {
62     fprintf(stderr, "unable to select 44.1kHz sample-rate -> no sound\n");
63     return;
64     }
65    
66     if (ioctl(fd, AUDIO_SET_CHANNELS, 1)) {
67     fprintf(stderr, "unable to select 1-channel playback -> no sound\n");
68     return;
69     }
70    
71     // choose between:
72     // AUDIO_OUT_SPEAKER
73     // AUDIO_OUT_HEADPHONE
74     // AUDIO_OUT_LINE
75     if (ioctl(fd, AUDIO_SET_OUTPUT, AUDIO_OUT_SPEAKER)) {
76     fprintf(stderr, "unable to select audio output -> no sound\n");
77     return;
78     }
79    
80     {
81     // set volume:
82     audio_describe description;
83     audio_gains gains;
84     if (ioctl(fd, AUDIO_DESCRIBE, &description)) {
85     fprintf(stderr, "unable to get audio description -> no sound\n");
86     return;
87     }
88     if (ioctl (fd, AUDIO_GET_GAINS, &gains)) {
89     fprintf(stderr, "unable to get gain values -> no sound\n");
90     return;
91     }
92    
93     float volume = 1.0;
94     gains.transmit_gain = (int)((float)description.min_transmit_gain +
95     (float)(description.max_transmit_gain
96     - description.min_transmit_gain)
97     * volume);
98     if (ioctl (fd, AUDIO_SET_GAINS, &gains)) {
99     fprintf(stderr, "unable to set gain values -> no sound\n");
100     return;
101     }
102     }
103    
104     if (ioctl(fd, AUDIO_SET_TXBUFSIZE, TXBUFSIZE)) {
105     fprintf(stderr, "unable to set transmission buffer size -> no sound\n");
106     return;
107     }
108    
109     sound_calc_buf = new int16[TXFRAGSIZE];
110    
111     linecnt = 0;
112    
113     ready = true;
114     return;
115     }
116    
117    
118     /*
119     * Destructor
120     */
121    
122     DigitalRenderer::~DigitalRenderer()
123     {
124     if (fd > 0) {
125     if (ready) {
126     ioctl(fd, AUDIO_DRAIN);
127     }
128     ioctl(fd, AUDIO_RESET);
129     close(fd);
130     }
131     }
132    
133    
134     /*
135     * Pause sound output
136     */
137    
138     void DigitalRenderer::Pause(void)
139     {
140     }
141    
142    
143     /*
144     * Resume sound output
145     */
146    
147     void DigitalRenderer::Resume(void)
148     {
149     }
150    
151    
152     /*
153     * Fill buffer, sample volume (for sampled voice)
154     */
155    
156     void DigitalRenderer::EmulateLine(void)
157     {
158     sample_buf[sample_in_ptr] = volume;
159     sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
160    
161     // testing the audio status at each raster-line is
162     // really not necessary. Let's do it every 50th one..
163     // ought to be enough by far.
164    
165     linecnt--;
166     if (linecnt < 0 && ready) {
167     linecnt = 50;
168    
169     // check whether we should add some more data to the
170     // transmission buffer.
171    
172     if (ioctl(fd, AUDIO_GET_STATUS, &status)) {
173     fprintf(stderr,"fatal: unable to get audio status\n");
174     exit(20);
175     }
176    
177     if (status.transmit_buffer_count < TXLOWWATER) {
178     // add one sound fragment..
179     calc_buffer(sound_calc_buf, TXFRAGSIZE*2);
180    
181     // since we've checked for enough space in the transmission buffer,
182     // it is an error if the non-blocking write returns anything but
183     // TXFRAGSIZE*2
184     if (TXFRAGSIZE*2 != write (fd, sound_calc_buf, TXFRAGSIZE*2)) {
185     fprintf(stderr,"fatal: write to audio-device failed\n");
186     exit(20);
187     }
188     }
189     }
190     }
191