1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * Support for SDL sound
5   *
6   * Copyright 1997 Bernd Schmidt
7   */
8 
9 #define SOUNDSTUFF 1
10 #define AUDIO_NAME "sdl"
11 
12 extern uae_u16 paula_sndbuffer[];
13 extern uae_u16 *paula_sndbufpt;
14 extern int paula_sndbufsize;
15 extern void finish_sound_buffer (void);
16 extern void restart_sound_buffer (void);
17 extern int init_sound (void);
18 extern void close_sound (void);
19 extern int setup_sound (void);
20 extern void resume_sound (void);
21 extern void pause_sound (void);
22 extern void reset_sound (void);
23 extern void sound_setadjust (double);
24 extern int enumerate_sound_devices (void);
25 extern int drivesound_init (void);
26 extern void drivesound_free (void);
27 extern void sound_mute (int);
28 extern void sound_volume (int);
29 extern void set_volume (int, int);
30 extern void master_sound_volume (int);
31 
32 struct sound_dp;
33 
34 struct sound_data
35 {
36 	int waiting_for_buffer;
37 	int devicetype;
38 	int obtainedfreq;
39 	int paused;
40 	int mute;
41 	int channels;
42 	int freq;
43 	int samplesize;
44 	int sndbufsize;
45 	struct sound_dp *data;
46 };
47 
48 
49 void send_sound (struct sound_data *sd, uae_u16 *sndbuffer);
50 int open_sound_device (struct sound_data *sd, int index, int exclusive, int bufsize, int freq, int channels);
51 void close_sound_device (struct sound_data *sd);
52 void pause_sound_device (struct sound_data *sd);
53 void resume_sound_device (struct sound_data *sd);
54 void set_volume_sound_device (struct sound_data *sd, int volume, int mute);
55 int get_offset_sound_device (struct sound_data *sd);
56 int blocking_sound_device (struct sound_data *sd);
57 
58 void audio_default_options (struct uae_prefs *p);
59 void audio_save_options (FILE *f, const struct uae_prefs *p);
60 int audio_parse_option (struct uae_prefs *p, const char *option, const char *value);
61 
62 
63 #if SOUNDSTUFF > 0
64 extern int outputsample, doublesample;
65 #endif
66 
67 #if SOUNDSTUFF > 1
68 static uae_u16 *paula_sndbufpt_prev, *paula_sndbufpt_start;
69 #endif // SOUNDSTUFF
70 
set_sound_buffers(void)71 STATIC_INLINE void set_sound_buffers (void)
72 {
73 #if SOUNDSTUFF > 1
74     paula_sndbufpt_prev = paula_sndbufpt_start;
75     paula_sndbufpt_start = paula_sndbufpt;
76 #endif
77 }
78 
check_sound_buffers(void)79 STATIC_INLINE void check_sound_buffers (void)
80 {
81 #if SOUNDSTUFF > 1
82 	int len;
83 #endif
84 
85 	if (currprefs.sound_stereo == SND_4CH_CLONEDSTEREO) {
86 		((uae_u16*)paula_sndbufpt)[0] = ((uae_u16*)paula_sndbufpt)[-2];
87 		((uae_u16*)paula_sndbufpt)[1] = ((uae_u16*)paula_sndbufpt)[-1];
88 		paula_sndbufpt = (uae_u16 *)(((uae_u8 *)paula_sndbufpt) + 2 * 2);
89 	} else if (currprefs.sound_stereo == SND_6CH_CLONEDSTEREO) {
90 		uae_s16 *p = ((uae_s16*)paula_sndbufpt);
91 		uae_s32 sum;
92 		p[2] = p[-2];
93 		p[3] = p[-1];
94 		sum = (uae_s32)(p[-2]) + (uae_s32)(p[-1]) + (uae_s32)(p[2]) + (uae_s32)(p[3]);
95 		p[0] = sum / 8;
96 		p[1] = sum / 8;
97 		paula_sndbufpt = (uae_u16 *)(((uae_u8 *)paula_sndbufpt) + 4 * 2);
98 	}
99 #if SOUNDSTUFF > 1
100 	if (outputsample == 0)
101 		return;
102 	len = paula_sndbufpt - paula_sndbufpt_start;
103 	if (outputsample < 0) {
104 		int i;
105 		uae_s16 *p1 = (uae_s16*)paula_sndbufpt_prev;
106 		uae_s16 *p2 = (uae_s16*)paula_sndbufpt_start;
107 		for (i = 0; i < len; i++) {
108 			*p1 = (*p1 + *p2) / 2;
109 		}
110 		paula_sndbufpt = paula_sndbufpt_start;
111 	}
112 #endif
113     if ((uae_u8*)paula_sndbufpt - (uae_u8*)paula_sndbuffer >= paula_sndbufsize) {
114 		finish_sound_buffer ();
115 		paula_sndbufpt = paula_sndbuffer;
116     }
117 #if SOUNDSTUFF > 1
118 	while (doublesample-- > 0) {
119 		memcpy (paula_sndbufpt, paula_sndbufpt_start, len * 2);
120 		paula_sndbufpt += len;
121 		if ((uae_u8*)paula_sndbufpt - (uae_u8*)paula_sndbuffer >= paula_sndbufsize) {
122 			finish_sound_buffer ();
123 			paula_sndbufpt = paula_sndbuffer;
124 		}
125 	}
126 #endif
127 }
128 
clear_sound_buffers(void)129 STATIC_INLINE void clear_sound_buffers (void)
130 {
131     memset (paula_sndbuffer, 0, paula_sndbufsize);
132     paula_sndbufpt = paula_sndbuffer;
133 }
134 
135 #define PUT_SOUND_WORD(b) do { *(uae_u16 *)paula_sndbufpt = b; paula_sndbufpt = (uae_u16 *)(((uae_u8 *)paula_sndbufpt) + 2); } while (0)
136 #define PUT_SOUND_WORD_LEFT(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[0]); PUT_SOUND_WORD(b); } while (0)
137 #define PUT_SOUND_WORD_RIGHT(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[1]); PUT_SOUND_WORD(b); } while (0)
138 #define PUT_SOUND_WORD_LEFT2(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[2]); PUT_SOUND_WORD(b); } while (0)
139 #define PUT_SOUND_WORD_RIGHT2(b) do { if (currprefs.sound_filter) b = filter (b, &sound_filter_state[3]); PUT_SOUND_WORD(b); } while (0)
140 
141 #define PUT_SOUND_WORD_MONO(b) PUT_SOUND_WORD_LEFT(b)
142 #define SOUND16_BASE_VAL 0
143 #define SOUND8_BASE_VAL 128
144 
145 #define DEFAULT_SOUND_MAXB 16384
146 #define DEFAULT_SOUND_MINB 16384
147 #define DEFAULT_SOUND_BITS 16
148 #define DEFAULT_SOUND_FREQ 44100
149 #define HAVE_STEREO_SUPPORT
150 
151 #define FILTER_SOUND_OFF 0
152 #define FILTER_SOUND_EMUL 1
153 #define FILTER_SOUND_ON 2
154 
155 #define FILTER_SOUND_TYPE_A500 0
156 #define FILTER_SOUND_TYPE_A1200 1
157