1
/*============================================================================
5
// SS tttttt eeee ll ll aaaa
6
// SSSS tt ee ee ll ll aa
7
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8
// SS SS tt ee ll ll aa aa
9
// SSSS ttt eeeee llll llll aaaaa
11
// Copyright (c) 1995-1998 by Bradford W. Mott
13
// See the file "license" for information on usage and redistribution of
14
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16
// $Id: OSS.c,v 1.1 1998/07/15 20:58:09 bwmott Exp $
17
//==========================================================================*/
20
This file implements the "stella-sound" process for the
21
Open Sound System (OSS) API.
23
@author Bradford W. Mott
24
@version $Id: OSS.c,v 1.1 1998/07/15 20:58:09 bwmott Exp $
30
#include <sys/ioctl.h>
32
#include <sys/types.h>
36
#include <machine/soundcard.h>
38
#include <sys/soundcard.h>
44
Compute Fragment size to use based on the sample rate
46
@param sampleRate The sample rate to compute the fragment size for
48
unsigned long computeFragmentSize(int sampleRate);
51
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
52
int main(int argc, char* argv[])
55
int numberAndSizeOfFragments;
57
unsigned char* fragmentBuffer;
63
/* Open the sound device for writing */
64
if((fd = open("/dev/dsp", O_WRONLY, 0)) == -1)
66
printf("stella-sound: Unable to open /dev/dsp device!\n");
70
/* Set the AUDIO DATA FORMAT */
72
if(ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1)
74
printf("stella-sound: Unable to set 8-bit sample mode!\n");
80
printf("stella-sound: Sound card doesn't support 8-bit sample mode!\n");
86
if(ioctl(fd, SNDCTL_DSP_STEREO, &stereo) == -1)
88
printf("stella-sound: Sound card doesn't support mono mode!\n");
94
printf("stella-sound: Sound card doesn't support mono mode!\n");
98
/* Set the SAMPLE RATE */
100
if(ioctl(fd, SNDCTL_DSP_SPEED, &sampleRate) == -1)
102
printf("stella-sound: Unable to set sample rate for /dev/dsp!\n");
106
/* Set the NUMBER AND SIZE OF FRAGMENTS */
107
numberAndSizeOfFragments = 0x00020000 | computeFragmentSize(sampleRate);
108
if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &numberAndSizeOfFragments) == -1)
110
printf("stella-sound: Unable to set fragment size!\n");
114
/* Query for the actual fragment size */
115
ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &fragmentSize);
117
/* Allocate fragment buffer */
118
fragmentBuffer = (unsigned char*)malloc(fragmentSize);
121
/* Initialize the TIA Sound Library */
122
Tia_sound_init(31400, sampleRate);
125
/* Make sure STDIN is in nonblocking mode */
126
if(fcntl(0, F_SETFL, O_NONBLOCK) == -1)
128
printf("stella-sound: Couldn't set non-blocking mode\n");
132
/* Loop reading commands from the emulator and playing sound fragments */
141
unsigned char input[1024];
143
/* Read as many commands as available */
144
n = read(0, input, 1024);
146
/* Process all of the commands we read */
147
for(i = 0; i < n; ++i)
149
unsigned char value = input[i];
151
switch((value >> 5) & 0x07)
153
case 0: /* Set AUDC0 */
154
Update_tia_sound(0x15, value);
157
case 1: /* Set AUDC1 */
158
Update_tia_sound(0x16, value);
161
case 2: /* Set AUDF0 */
162
Update_tia_sound(0x17, value);
165
case 3: /* Set AUDF1 */
166
Update_tia_sound(0x18, value);
169
case 4: /* Set AUDV0 */
170
Update_tia_sound(0x19, value);
173
case 5: /* Set AUDV1 */
174
Update_tia_sound(0x1A, value);
182
case 7: /* Change mute command */
193
/* If sound isn't muted then play something */
196
/* Create the next fragment to play */
197
Tia_process(fragmentBuffer, fragmentSize);
199
/* Write fragment to sound device */
200
write(fd, fragmentBuffer, fragmentSize);
204
/* Sound is muted so let's sleep for a little while */
205
struct timeval timeout;
207
timeout.tv_usec = 10000;
208
select(0, 0, 0, 0, &timeout);
213
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
214
unsigned long computeFragmentSize(int sampleRate)
218
for(t = 7; t < 24; ++t)
220
if((1 << t) > (sampleRate / 60))
224
/* Default to 256 byte fragment size */