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 (20 years, 9 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
updated copyright date

File Contents

# Content
1 /*
2 * SID_linux.h - 6581 emulation, Linux specific stuff
3 *
4 * Frodo (C) 1994-1997,2002-2003 Christian Bauer
5 *
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 }