ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/SID_linux.h
Revision: 1.7
Committed: 2010-04-22T09:09:28Z (14 years, 5 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +1 -88 lines
Log Message:
use SDL for sound

File Contents

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