~ubuntu-branches/debian/squeeze/stella/squeeze

« back to all changes in this revision

Viewing changes to src/ui/sound/OSS.c

  • Committer: Bazaar Package Importer
  • Author(s): Tom Lear
  • Date: 1999-11-06 16:41:05 UTC
  • Revision ID: james.westby@ubuntu.com-19991106164105-iygopamo5mpcozvx
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*============================================================================
 
2
//
 
3
//   SSSS    tt          lll  lll
 
4
//  SS  SS   tt           ll   ll
 
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
 
10
//   
 
11
// Copyright (c) 1995-1998 by Bradford W. Mott
 
12
// 
 
13
// See the file "license" for information on usage and redistribution of
 
14
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
15
// 
 
16
// $Id: OSS.c,v 1.1 1998/07/15 20:58:09 bwmott Exp $
 
17
//==========================================================================*/
 
18
 
 
19
/**
 
20
  This file implements the "stella-sound" process for the 
 
21
  Open Sound System (OSS) API.
 
22
 
 
23
  @author  Bradford W. Mott
 
24
  @version $Id: OSS.c,v 1.1 1998/07/15 20:58:09 bwmott Exp $
 
25
*/
 
26
 
 
27
#include <fcntl.h>
 
28
#include <stdio.h>
 
29
#include <stdlib.h>
 
30
#include <sys/ioctl.h>
 
31
#include <sys/time.h>
 
32
#include <sys/types.h>
 
33
#include <unistd.h>
 
34
 
 
35
#ifdef __FreeBSD__
 
36
  #include <machine/soundcard.h>
 
37
#else
 
38
  #include <sys/soundcard.h>
 
39
#endif
 
40
 
 
41
#include "TIASound.h"
 
42
 
 
43
/**
 
44
  Compute Fragment size to use based on the sample rate 
 
45
 
 
46
  @param sampleRate The sample rate to compute the fragment size for
 
47
*/
 
48
unsigned long computeFragmentSize(int sampleRate);
 
49
 
 
50
 
 
51
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
52
int main(int argc, char* argv[])
 
53
{
 
54
  int fd;
 
55
  int numberAndSizeOfFragments;
 
56
  int fragmentSize;
 
57
  unsigned char* fragmentBuffer;
 
58
  int sampleRate;
 
59
  int format;
 
60
  int stereo;
 
61
  int mute = 0;
 
62
 
 
63
  /* Open the sound device for writing */
 
64
  if((fd = open("/dev/dsp", O_WRONLY, 0)) == -1)
 
65
  {
 
66
    printf("stella-sound: Unable to open /dev/dsp device!\n");
 
67
    return 1;
 
68
  }
 
69
 
 
70
  /* Set the AUDIO DATA FORMAT */
 
71
  format = AFMT_U8;
 
72
  if(ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1)
 
73
  {
 
74
    printf("stella-sound: Unable to set 8-bit sample mode!\n");
 
75
    return 1;
 
76
  }
 
77
 
 
78
  if(format != AFMT_U8)
 
79
  {
 
80
    printf("stella-sound: Sound card doesn't support 8-bit sample mode!\n");
 
81
    return 1;
 
82
  }
 
83
 
 
84
  /* Set MONO MODE */
 
85
  stereo = 0;
 
86
  if(ioctl(fd, SNDCTL_DSP_STEREO, &stereo) == -1)
 
87
  {
 
88
    printf("stella-sound: Sound card doesn't support mono mode!\n");
 
89
    return 1;
 
90
  }
 
91
 
 
92
  if(stereo != 0)
 
93
  {
 
94
    printf("stella-sound: Sound card doesn't support mono mode!\n");
 
95
    return 1;
 
96
  }
 
97
 
 
98
  /* Set the SAMPLE RATE */
 
99
  sampleRate = 31400;
 
100
  if(ioctl(fd, SNDCTL_DSP_SPEED, &sampleRate) == -1)
 
101
  {
 
102
    printf("stella-sound: Unable to set sample rate for /dev/dsp!\n");
 
103
    return 1;
 
104
  }
 
105
 
 
106
  /* Set the NUMBER AND SIZE OF FRAGMENTS */
 
107
  numberAndSizeOfFragments = 0x00020000 | computeFragmentSize(sampleRate);
 
108
  if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &numberAndSizeOfFragments) == -1)
 
109
  {
 
110
    printf("stella-sound: Unable to set fragment size!\n");
 
111
    return 1;
 
112
  }
 
113
  
 
114
  /* Query for the actual fragment size */
 
115
  ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &fragmentSize);
 
116
 
 
117
  /* Allocate fragment buffer */
 
118
  fragmentBuffer = (unsigned char*)malloc(fragmentSize);
 
119
 
 
120
 
 
121
  /* Initialize the TIA Sound Library */
 
122
  Tia_sound_init(31400, sampleRate);
 
123
 
 
124
 
 
125
  /* Make sure STDIN is in nonblocking mode */
 
126
  if(fcntl(0, F_SETFL, O_NONBLOCK) == -1)
 
127
  {
 
128
    printf("stella-sound: Couldn't set non-blocking mode\n");
 
129
    return 1;
 
130
  }
 
131
 
 
132
  /* Loop reading commands from the emulator and playing sound fragments */
 
133
  for(;;)
 
134
  {
 
135
    int done = 0;
 
136
 
 
137
    while(!done)
 
138
    {
 
139
      int i;
 
140
      int n;
 
141
      unsigned char input[1024];
 
142
 
 
143
      /* Read as many commands as available */
 
144
      n = read(0, input, 1024);
 
145
 
 
146
      /* Process all of the commands we read */
 
147
      for(i = 0; i < n; ++i)
 
148
      {
 
149
        unsigned char value = input[i];
 
150
 
 
151
        switch((value >> 5) & 0x07)
 
152
        {
 
153
          case 0:    /* Set AUDC0 */
 
154
            Update_tia_sound(0x15, value);
 
155
            break;
 
156
 
 
157
          case 1:    /* Set AUDC1 */
 
158
            Update_tia_sound(0x16, value);
 
159
            break;
 
160
 
 
161
          case 2:    /* Set AUDF0 */
 
162
            Update_tia_sound(0x17, value);
 
163
            break;
 
164
 
 
165
          case 3:    /* Set AUDF1 */
 
166
            Update_tia_sound(0x18, value);
 
167
            break;
 
168
 
 
169
          case 4:    /* Set AUDV0 */
 
170
            Update_tia_sound(0x19, value);
 
171
            break;
 
172
 
 
173
          case 5:    /* Set AUDV1 */
 
174
            Update_tia_sound(0x1A, value);
 
175
            break;
 
176
 
 
177
          case 6:    /* Quit */
 
178
            close(fd);
 
179
            return 1;
 
180
            break;
 
181
 
 
182
          case 7:    /* Change mute command */
 
183
            mute = value & 0x01;
 
184
            break;
 
185
 
 
186
          default:
 
187
            break;
 
188
        }
 
189
      }
 
190
      done = (n != 1024);   
 
191
    } 
 
192
 
 
193
    /* If sound isn't muted then play something */
 
194
    if(!mute)
 
195
    {
 
196
      /* Create the next fragment to play */
 
197
      Tia_process(fragmentBuffer, fragmentSize);
 
198
 
 
199
      /* Write fragment to sound device */
 
200
      write(fd, fragmentBuffer, fragmentSize);
 
201
    }
 
202
    else
 
203
    {
 
204
      /* Sound is muted so let's sleep for a little while */
 
205
      struct timeval timeout;
 
206
      timeout.tv_sec = 0;
 
207
      timeout.tv_usec = 10000;
 
208
      select(0, 0, 0, 0, &timeout);
 
209
    }
 
210
  }
 
211
}
 
212
 
 
213
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 
214
unsigned long computeFragmentSize(int sampleRate)
 
215
{
 
216
  int t;
 
217
 
 
218
  for(t = 7; t < 24; ++t) 
 
219
  {
 
220
    if((1 << t) > (sampleRate / 60))
 
221
      return t - 1;
 
222
  }
 
223
 
 
224
  /* Default to 256 byte fragment size */
 
225
  return 8;
 
226
}
 
227