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