|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Support for Digital Unix/MME
5: *
6: * Copyright 1997 Marcus Sundberg
7: */
8:
9: #define MME_SOUND_C
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12: #include "config.h"
13: #include "options.h"
14: #include "memory.h"
1.1.1.2 ! root 15: #include "events.h"
1.1 root 16: #include "custom.h"
17: #include "audio.h"
18: #include "gensound.h"
19: #include "sounddep/sound.h"
20:
21: /*#include <sys/ioctl.h>*/
22: #include <mme/mme_api.h>
23:
24: HWAVEOUT mme_handle = 0;
25: LPSTR mme_audiobuf = NULL;
26: LPWAVEHDR WaveHeader = NULL;
27: static char *mme_sndbufpt;
28:
29: static int have_sound;
30: static int bytes_per_sample;
31:
32: uae_u16 *sndbuffer;
33: uae_u16 *sndbufpt;
34: int sndbufsize;
35: int mme_free_bufs = 0, mme_nextbuf = 0;
36:
37:
38: /* callbackfunction used by mme */
39: static void mme_callback(HANDLE hWaveOut,
40: UINT wMsg,
41: DWORD dwInstance,
42: LPARAM lParam1,
43: LPARAM lParam2)
44: {
45: switch(wMsg) {
46: case WOM_OPEN:
47: case WOM_CLOSE:
48: /* Ignore these */
49: break;
50: case WOM_DONE:
51: mme_free_bufs--;
52: break;
53: default:
54: break;
55: }
56: }
57:
58: void close_sound(void)
59: {
60: if (have_sound) {
61: mmeFreeMem(WaveHeader);
62: mmeFreeBuffer(mme_audiobuf);
63: waveOutClose(mme_handle);
64: }
65: mme_handle=0;
66: }
67:
68: int setup_sound(void)
69: {
70: if (waveOutGetNumDevs() < 1) {
71: have_sound = 0;
72: return 0;
73: }
74: have_sound = 1;
75:
76: sound_available = 1;
77: return 1;
78: }
79:
80: int init_sound (void)
81: {
82: int rate;
83: int dspbits;
84: int channels;
85: MMRESULT status;
86: LPPCMWAVEFORMAT waveformat;
87:
88: if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) {
89: fprintf(stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz);
90: currprefs.sound_maxbsiz = 8192;
91: }
92:
93: sndbufsize = currprefs.sound_maxbsiz;
94:
95: dspbits = currprefs.sound_bits;
96:
97: rate = currprefs.sound_freq;
98:
99: channels = 1;
100:
101: if((waveformat = (LPPCMWAVEFORMAT)
102: mmeAllocMem(sizeof(PCMWAVEFORMAT))) == NULL ) {
103: fprintf(stderr, "Failed to allocate PCMWAVEFORMAT struct\n");
104: return 0;
105: }
106: waveformat->wf.nSamplesPerSec = rate;
107: waveformat->wf.nChannels = channels;
108: waveformat->wBitsPerSample = dspbits;
109: waveformat->wf.wFormatTag = WAVE_FORMAT_PCM;
110:
111: bytes_per_sample = waveformat->wf.nChannels *
112: (waveformat->wBitsPerSample/8);
113: waveformat->wf.nBlockAlign = bytes_per_sample;
114: waveformat->wf.nAvgBytesPerSec = bytes_per_sample *
115: waveformat->wf.nSamplesPerSec;
116:
117: /* Open the audio device with desired rate/format */
118: status = waveOutOpen( &mme_handle,
119: WAVE_MAPPER,
120: (LPWAVEFORMAT)waveformat,
121: (void (*)())mme_callback,
122: (unsigned int)NULL,
123: CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE );
124: mmeFreeMem(waveformat);
125:
126: if(status != MMSYSERR_NOERROR) {
127: fprintf(stderr, "waveOutOpen failed - status = %d\n", status);
128: return 0;
129: }
130:
131: /* Allocate wave header for use in write */
132: if((WaveHeader = (LPWAVEHDR)
133: mmeAllocMem(sizeof(WAVEHDR))) == NULL ) {
134: fprintf(stderr, "Failed to allocate WAVEHDR struct\n");
135: return 0;
136: }
137: /* Allocate shared audio buffer for communicating with audio device */
138: if ((mme_audiobuf = (LPSTR)
139: mmeAllocBuffer(sndbufsize*SOUND_NUMBUF*bytes_per_sample*2)) == NULL) {
140: fprintf(stderr, "Failed to allocate shared audio buffer\n");
141: mmeFreeMem(WaveHeader);
142: return 0;
143: }
144: sndbuffer = mme_audiobuf;
1.1.1.2 ! root 145: scaled_sample_evtime = (unsigned long)maxhpos * maxvpos * vblank_hz * CYCLE_UNIT / rate;
! 146: scaled_sample_evtime_ok = 1;
1.1 root 147:
148: if (dspbits == 16) {
149: init_sound_table16 ();
150: sample_handler = sample16_handler;
151: } else {
152: init_sound_table8 ();
153: sample_handler = sample8_handler;
154: }
155: sound_available = 1;
156: printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n", dspbits, rate, sndbufsize);
157: mme_sndbufpt = sndbufpt = sndbuffer;
158: return 1;
159: }
160:
161:
162: __inline__ void check_sound_buffers (void)
163: {
164: if (((char *)sndbufpt - (char *)mme_sndbufpt) < sndbufsize)
165: return;
166: if (mmeCheckForCallbacks())
167: mmeProcessCallbacks();
168: if (mme_free_bufs >= SOUND_NUMBUF)
169: return;
170: WaveHeader->lpData = (LPSTR)mme_sndbufpt;
171: WaveHeader->dwBufferLength = ((char *)sndbufpt - (char *)mme_sndbufpt);
172: mme_nextbuf++;
173: if (mme_nextbuf == SOUND_NUMBUF) {
174: mme_sndbufpt = sndbuffer;
175: mme_nextbuf = 0;
176: }
177: else mme_sndbufpt += bytes_per_sample*sndbufsize*2;
178: sndbufpt = mme_sndbufpt;
179: if (waveOutWrite(mme_handle, WaveHeader,
180: sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
181: mme_free_bufs++;
182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.