ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/SID_linux.h
Revision: 1.2
Committed: 2003-07-01T17:51:17Z (19 years, 7 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
updated copyright date

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * SID_linux.h - 6581 emulation, Linux specific stuff
3     *
4 cebix 1.2 * Frodo (C) 1994-1997,2002-2003 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     #include <unistd.h>
22     #include <fcntl.h>
23     #include <sys/ioctl.h>
24     #include <linux/soundcard.h>
25    
26     #include "VIC.h"
27    
28    
29     /*
30     * Initialization
31     */
32    
33     void DigitalRenderer::init_sound(void)
34     {
35     int tmp;
36     unsigned long format;
37    
38     ready = false;
39     devfd = open("/dev/dsp", O_WRONLY);
40     if (devfd < 0)
41     return;
42    
43     ioctl(devfd, SNDCTL_DSP_GETFMTS, &format);
44     if (!(format & AFMT_S16_LE))
45     return;
46     format = AFMT_S16_LE;
47     ioctl(devfd, SNDCTL_DSP_SETFMT, &format);
48    
49     /*
50     * Buffer size: 2^9 == 512 bytes. Note that too large buffers will not work
51     * very well: The speed of the C64 is slowed down to an average speed of
52     * 100% by the blocking write() call in EmulateLine(). If you use a buffer
53     * of, say 4096 bytes, that will happen only about every 4 frames, which
54     * means that the emulation runs much faster in some frames, and much
55     * slower in others.
56     * On really fast machines, it might make sense to use an even smaller
57     * buffer size.
58     */
59     tmp = 0x00100009;
60     ioctl(devfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
61     tmp = 0;
62     ioctl(devfd, SNDCTL_DSP_STEREO, &tmp);
63     tmp = 44100;
64     ioctl(devfd, SNDCTL_DSP_SPEED, &tmp);
65     ioctl(devfd, SOUND_PCM_READ_RATE, &tmp);
66     if (tmp < 43000 || tmp > 45000)
67     return;
68    
69     ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
70     sound_buffer = new int16[sndbufsize];
71     ready = true;
72     }
73    
74    
75     /*
76     * Destructor
77     */
78    
79     DigitalRenderer::~DigitalRenderer()
80     {
81     if (devfd >= 0)
82     close(devfd);
83     }
84    
85    
86     /*
87     * Pause sound output
88     */
89    
90     void DigitalRenderer::Pause(void)
91     {
92     }
93    
94    
95     /*
96     * Resume sound output
97     */
98    
99     void DigitalRenderer::Resume(void)
100     {
101     }
102    
103    
104     /*
105     * Fill buffer, sample volume (for sampled voice)
106     */
107    
108     void DigitalRenderer::EmulateLine(void)
109     {
110     static int divisor = 0;
111     static int to_output = 0;
112     static int buffer_pos = 0;
113    
114     if (!ready)
115     return;
116    
117     sample_buf[sample_in_ptr] = volume;
118     sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
119    
120     /*
121     * Now see how many samples have to be added for this line
122     */
123     divisor += SAMPLE_FREQ;
124     while (divisor >= 0)
125     divisor -= TOTAL_RASTERS*SCREEN_FREQ, to_output++;
126    
127     /*
128     * Calculate the sound data only when we have enough to fill
129     * the buffer entirely.
130     */
131     if ((buffer_pos + to_output) >= sndbufsize) {
132     int datalen = sndbufsize - buffer_pos;
133     to_output -= datalen;
134     calc_buffer(sound_buffer + buffer_pos, datalen*2);
135     write(devfd, sound_buffer, sndbufsize*2);
136     buffer_pos = 0;
137     }
138     }