|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Win32 interface
5: *
6: * Copyright 1997 Mathias Ortmann
7: */
8:
9: #ifdef __GNUC__
10: #define __int64 long long
11: #include "machdep/winstuff.h"
12: #else
13: #include <windows.h>
14: #include <ddraw.h>
15: #include <stdlib.h>
16: #include <stdarg.h>
17: #include <commctrl.h>
18: #include <commdlg.h>
19: #include <stdio.h>
20: #include <fcntl.h>
21: #include <sys/stat.h>
22: #include <io.h>
23: #endif
24:
25: #include "config.h"
26: #include "sysconfig.h"
27: #include "sysdeps.h"
28: #include "options.h"
29: #include "gensound.h"
30: #include "sounddep/sound.h"
31: #include "events.h"
32: #include "uae.h"
33: #include "include/memory.h"
34: #include "custom.h"
35: #include "osdep/win32gui.h"
36: #include "resource.h"
37: #include "osdep/win32.h"
38:
39: /* Sound emulation, Win32 interface */
40: HGLOBAL hWaveHdr;
41: LPWAVEHDR lpWaveHdr;
42: HANDLE hData;
43: LPSTR lpData;
44: HANDLE hWaveOut;
45:
46: static WAVEFORMATEX wavfmt;
47: char *sndptr, *sndptrmax, soundneutral;
48: signed int bytesinbuf;
49: static HGLOBAL hSndbuf;
50: MMTIME mmtime;
51: static DWORD basevsynctime;
52:
53: int stereo_sound;
54:
55: signed long bufsamples;
56: int samplecount;
57: DWORD soundbufsize;
58:
59: void close_sound (void)
60: {
61: if (hWaveOut) {
62: waveOutReset (hWaveOut);
63: waveOutUnprepareHeader (hWaveOut, lpWaveHdr, sizeof (WAVEHDR));
64:
65: GlobalUnlock (hWaveHdr);
66: GlobalFree (lpWaveHdr);
67:
68: GlobalUnlock (hData);
69: GlobalFree (hData);
70:
71: waveOutClose (hWaveOut);
72:
73: hWaveOut = NULL;
74: }
75: }
76:
77: void startsound (void)
78: {
79: lpWaveHdr->lpData = lpData;
80: lpWaveHdr->dwBufferLength = soundbufsize;
81: lpWaveHdr->dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
82: lpWaveHdr->dwLoops = 0x7fffffffL;
83: waveOutPrepareHeader (hWaveOut, lpWaveHdr, sizeof (WAVEHDR));
84:
85: if (waveOutWrite (hWaveOut, lpWaveHdr, sizeof (WAVEHDR))) {
86: MyOutputDebugString ("Failed to write to sound card\n");
87: return;
88: }
89: }
90:
91: void stopsound (void)
92: {
93: sndptr = lpData;
94: samplecount = 0;
95: memset (lpData, soundneutral, soundbufsize);
96: waveOutReset (hWaveOut);
97: }
98:
99: static int init_sound_win32 (void)
100: {
101: MMRESULT mmres;
102: DWORD id;
103: long i;
104: __int64 freq;
105:
106: if (currprefs.produce_sound < 0) {
107: currprefs.produce_sound = 0;
108: MyOutputDebugString ("FrameSync disabled.\n");
109: } else {
110: #ifdef FRAME_RATE_HACK
111: if (!vsynctime) {
112: DWORD oldpri = GetPriorityClass (GetCurrentProcess ());
113:
114: MyOutputDebugString ("Measuring clock rate...\n");
115:
116: SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS);
117: i = read_processor_time ();
118: Sleep (1000);
119: i = read_processor_time () - i;
120: SetPriorityClass (GetCurrentProcess (), oldpri);
121:
122: MyOutputDebugString ("Your machine is running at approx. %d Hz\n", i);
123: vsynctime = i / 50;
124: } else if (vsynctime > 0)
125: vsynctime *= 1000 / 50;
126: else {
127: MyOutputDebugString ("Using QueryPerformanceCounter()...\n");
128: QueryPerformanceFrequency (&freq);
129: vsynctime = freq / 50;
130: useqpc = 1;
131: }
132:
133: if (!vsynctime)
134: MyOutputDebugString ("No performance counters available. Bad.\n");
135: else
136: MyOutputDebugString ("FrameSync enabled. Ticks per frame: %d\n", vsynctime);
137: #else
138: vsynctime = 0;
139: #endif
140: }
141:
142: if (currprefs.produce_sound < 2) {
143: MyOutputDebugString ("Sound output disabled.\n");
144: return 1;
145: }
146: mmtime.wType = TIME_SAMPLES;
147:
148: wavfmt.wFormatTag = WAVE_FORMAT_PCM;
149: wavfmt.nChannels = 1 + stereo_sound;
150: wavfmt.nSamplesPerSec = currprefs.sound_freq;
151: wavfmt.nBlockAlign = currprefs.sound_bits / 8 * wavfmt.nChannels;
152: wavfmt.nAvgBytesPerSec = wavfmt.nBlockAlign * currprefs.sound_freq;
153: wavfmt.wBitsPerSample = currprefs.sound_bits;
154:
155: soundneutral = currprefs.sound_bits == 8 ? 128 : 0;
156: bufsamples = 4096 * currprefs.sound_freq / 22050;
157: soundbufsize = bufsamples * wavfmt.nBlockAlign;
158:
159: if (!(hData = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, soundbufsize))) {
160: MyOutputDebugString ("Failed to allocate sound buffer!\n");
161: return 0;
162: }
163: if (!(lpData = GlobalLock (hData))) {
164: MyOutputDebugString ("Failed to lock sound buffer!\n");
165: return 0;
166: }
167: if (!(hWaveHdr = GlobalAlloc (GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof (WAVEHDR)))) {
168: MyOutputDebugString ("Failed to allocate wave header!\n");
169: return 0;
170: }
171: if (!(lpWaveHdr = (LPWAVEHDR) GlobalLock (hWaveHdr))) {
172: MyOutputDebugString ("Failed to lock wave header!\n");
173: return 0;
174: }
175: if (mmres = waveOutOpen (&hWaveOut, WAVE_MAPPER, &wavfmt, 0, 0, CALLBACK_NULL)) {
176: MyOutputDebugString ("Sound device failed to open with error code %d.\n", mmres);
177: return 0;
178: }
179: basevsynctime = vsynctime;
180: sndptrmax = lpData + soundbufsize;
181:
182: stopsound ();
183: startsound ();
184:
185: return currprefs.sound_freq;
186: }
187:
188: void adjust_sound_timing (void)
189: {
190: static DWORD last;
191: signed long diff;
192:
193: waveOutGetPosition (hWaveOut, &mmtime, sizeof (mmtime));
194: if (!mmtime.u.sample)
195: mmtime.u.sample++;
196:
197: if (last == mmtime.u.sample)
198: return;
199: last = mmtime.u.sample;
200:
201: diff = samplecount - mmtime.u.sample;
202:
203: if (diff < -bufsamples || diff > bufsamples) {
204: samplecount = mmtime.u.sample;
205: sndptr = lpData + (samplecount % bufsamples) * wavfmt.nBlockAlign;
206: }
207: if (diff < 0)
208: vsynctime = basevsynctime * 5 / 6;
209: else if (diff > 0)
210: vsynctime = basevsynctime * 7 / 6;
211: }
212:
213: int setup_sound (void)
214: {
215: sound_available = 1;
216: return 1;
217: }
218:
219: int init_sound (void)
220: {
221: int rate;
222:
223: if ((rate = init_sound_win32 ()) < 2)
224: return rate;
225:
226: sample_evtime = (long) maxhpos *maxvpos * 50 / rate;
227:
228: if (currprefs.sound_bits == 16) {
229: init_sound_table16 ();
230: eventtab[ev_sample].handler = sample16_handler;
231: } else {
232: init_sound_table8 ();
233: eventtab[ev_sample].handler = sample8_handler;
234: }
235:
236: MyOutputDebugString ("Sound driver found and configured for %d bits at %d Hz %s\n",
237: currprefs.sound_bits, rate, stereo_sound ? "stereo" : "");
238:
239: return 1;
240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.