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