1 #include "sysconfig.h"
2 #include "sysdeps.h"
3 
4 #include "include/uae.h"
5 #include "include/options.h"
6 #include "gensound.h"
7 #include "audio.h"
8 #include "uae/fs.h"
9 
10 int have_sound = 0;
11 
12 static float scaled_sample_evtime_orig;
13 static int obtainedfreq;
14 static float sound_sync_multiplier = 1.0;
15 
16 /* Originally from sampler.cpp (not used in FS-UAE) */
17 float sampler_evtime;
18 
19 static int (*g_audio_callback)(int type, int16_t *buffer, int size) = NULL;
20 static int g_audio_buffer_size = 512 * 2 * 2;
21 
22 struct sound_data
23 {
24 #if 0
25 	int waiting_for_buffer;
26 	int deactive;
27 	int devicetype;
28 #endif
29 	int obtainedfreq;
30 #if 0
31 	int paused;
32 	int mute;
33 	int channels;
34 	int freq;
35 	int samplesize;
36 	int sndbufsize;
37 	int sndbufframes;
38 	int softvolume;
39 	struct sound_dp *data;
40 #endif
41 };
42 
43 static struct sound_data sdpaula;
44 static struct sound_data *sdp = &sdpaula;
45 
46 static uae_u8 *extrasndbuf;
47 static int extrasndbufsize;
48 static int extrasndbuffered;
49 
amiga_set_audio_callback(audio_callback func)50 int amiga_set_audio_callback(audio_callback func)
51 {
52     g_audio_callback = func;
53     return 1;
54 }
55 
amiga_set_audio_buffer_size(int size)56 int amiga_set_audio_buffer_size(int size)
57 {
58     g_audio_buffer_size = size;
59     return 1;
60 }
61 
amiga_set_audio_frequency(int frequency)62 int amiga_set_audio_frequency(int frequency)
63 {
64     if (frequency == 0) {
65         /* Some code divides by frequency, so 0 is not a good idea */
66         write_log("WARNING: amiga_set_audio_frequency 0, set to 44100\n");
67         frequency = 44100;
68     }
69     char freq[13];
70     snprintf(freq, 13, "%d", frequency);
71     amiga_set_option("sound_frequency", freq);
72 
73     write_log("amiga_set_audio_frequency: %d\n", frequency);
74     sdp->obtainedfreq = frequency;
75     //changed_prefs.sound_freq = frequency;
76     //write_log("changed_prefs: %p\n", &changed_prefs);
77     //config_changed = 1;
78     return 1;
79 }
80 
update_sound(double clk)81 void update_sound (double clk)
82 {
83 	if (!have_sound)
84 		return;
85 	scaled_sample_evtime_orig = clk * CYCLE_UNIT * sound_sync_multiplier / sdp->obtainedfreq;
86 	scaled_sample_evtime = scaled_sample_evtime_orig;
87 	sampler_evtime = clk * CYCLE_UNIT * sound_sync_multiplier;
88 }
89 
90 
91 #if 0
92 void update_sound (double freq, int longframe, int linetoggle) {
93     static int lastfreq;
94     double lines = 0;
95     double hpos;
96 
97     if (freq < 0)
98         freq = lastfreq;
99     lastfreq = freq;
100 
101     if (!have_sound)
102         return;
103 
104     if (linetoggle) {
105         hpos = maxhpos_short + 0.5;
106         lines += 0.5;
107     } else {
108         if (longframe < 0)
109             lines += 0.5;
110         else if (longframe > 0)
111             lines += 1.0;
112         hpos = maxhpos_short;
113     }
114     lines += maxvpos_nom;
115 
116     scaled_sample_evtime = hpos * lines * freq * CYCLE_UNIT / (double) obtainedfreq;
117 #ifdef SAMPLER
118     sampler_evtime = hpos * lines * freq * CYCLE_UNIT;
119 #endif
120 }
121 #endif
122 
123 /*
124  * UAE - The Un*x Amiga Emulator
125  *
126  * Support for SDL sound
127  *
128  * Copyright 1997 Bernd Schmidt
129  * Copyright 2003-2006 Richard Drummond
130  * Copyright 2009-2010 Mustafa TUFAN
131  */
132 
133 #include "audio.h"
134 #include "uae/memory.h"
135 #include "events.h"
136 #include "custom.h"
137 #include "gui.h"
138 #include "gensound.h"
139 #include "driveclick.h"
140 #include "sounddep/sound.h"
141 #include "threaddep/thread.h"
142 //#include <SDL_audio.h>
143 
144 uae_u16 paula_sndbuffer[44100];
145 uae_u16 *paula_sndbufpt;
146 int paula_sndbufsize;
147 
clearbuffer(void)148 static void clearbuffer (void)
149 {
150     memset (paula_sndbuffer, 0, sizeof (paula_sndbuffer));
151 }
152 
channelswap(uae_s16 * sndbuffer,int len)153 static void channelswap (uae_s16 *sndbuffer, int len)
154 {
155 	int i;
156 	for (i = 0; i < len; i += 2) {
157 		uae_s16 t;
158 		t = sndbuffer[i];
159 		sndbuffer[i] = sndbuffer[i + 1];
160 		sndbuffer[i + 1] = t;
161 	}
162 }
163 
channelswap6(uae_s16 * sndbuffer,int len)164 static void channelswap6 (uae_s16 *sndbuffer, int len)
165 {
166 	int i;
167 	for (i = 0; i < len; i += 6) {
168 		uae_s16 t;
169 		t = sndbuffer[i + 0];
170 		sndbuffer[i + 0] = sndbuffer[i + 1];
171 		sndbuffer[i + 1] = t;
172 		t = sndbuffer[i + 4];
173 		sndbuffer[i + 4] = sndbuffer[i + 5];
174 		sndbuffer[i + 5] = t;
175 	}
176 }
177 
send_sound(struct sound_data * sd,uae_u16 * sndbuffer)178 static void send_sound (struct sound_data *sd, uae_u16 *sndbuffer)
179 {
180 #if 0
181 	if (savestate_state)
182 		return;
183 	if (sd->paused)
184 		return;
185 	if (sd->softvolume >= 0) {
186 		uae_s16 *p = (uae_s16*)sndbuffer;
187 		for (int i = 0; i < sd->sndbufsize / 2; i++) {
188 			p[i] = p[i] * sd->softvolume / 32768;
189 		}
190 	}
191 #endif
192 	if (g_audio_callback) {
193 		g_audio_callback(0, (int16_t *) paula_sndbuffer, paula_sndbufsize);
194 	}
195 }
196 
finish_sound_buffer(void)197 void finish_sound_buffer (void)
198 {
199 	static unsigned long tframe;
200 	int bufsize = (uae_u8*)paula_sndbufpt - (uae_u8*)paula_sndbuffer;
201 
202 	if (currprefs.turbo_emulation) {
203 		paula_sndbufpt = paula_sndbuffer;
204 		return;
205 	}
206 	if (currprefs.sound_stereo_swap_paula) {
207 		if (get_audio_nativechannels (currprefs.sound_stereo) == 2 || get_audio_nativechannels (currprefs.sound_stereo) == 4)
208 			channelswap((uae_s16*)paula_sndbuffer, bufsize / 2);
209 		else if (get_audio_nativechannels (currprefs.sound_stereo) == 6)
210 			channelswap6((uae_s16*)paula_sndbuffer, bufsize / 2);
211 	}
212 
213 #ifdef DRIVESOUND
214     driveclick_mix ((uae_s16*)paula_sndbuffer, paula_sndbufsize / 2, currprefs.dfxclickchannelmask);
215 #endif
216 	// must be after driveclick_mix
217 	paula_sndbufpt = paula_sndbuffer;
218 #ifdef AVIOUTPUT
219 	if (avioutput_enabled && avioutput_audio) {
220 		AVIOutput_WriteAudio((uae_u8*)paula_sndbuffer, bufsize);
221 		if (avioutput_nosoundsync)
222 			sound_setadjust(0);
223 	}
224 	if (avioutput_enabled && (!avioutput_framelimiter || avioutput_nosoundoutput))
225 		return;
226 #endif
227     if (!have_sound)
228         return;
229 
230 #if 0
231 	// we got buffer that was not full (recording active). Need special handling.
232 	if (bufsize < sdp->sndbufsize && !extrasndbuf) {
233 		extrasndbufsize = sdp->sndbufsize;
234 		extrasndbuf = xcalloc(uae_u8, sdp->sndbufsize);
235 		extrasndbuffered = 0;
236 	}
237 #endif
238 
239     static int statuscnt;
240     if (statuscnt > 0 && tframe != timeframes) {
241         tframe = timeframes;
242         statuscnt--;
243         if (statuscnt == 0)
244             gui_data.sndbuf_status = 0;
245     }
246     if (gui_data.sndbuf_status == 3)
247         gui_data.sndbuf_status = 0;
248 
249 	if (extrasndbuf) {
250 		int size = extrasndbuffered + bufsize;
251 		int copied = 0;
252 		if (size > extrasndbufsize) {
253 			copied = extrasndbufsize - extrasndbuffered;
254 			memcpy(extrasndbuf + extrasndbuffered, paula_sndbuffer, copied);
255 			send_sound(sdp, (uae_u16*)extrasndbuf);
256 			extrasndbuffered = 0;
257 		}
258 		memcpy(extrasndbuf + extrasndbuffered, (uae_u8*)paula_sndbuffer + copied, bufsize - copied);
259 		extrasndbuffered += bufsize - copied;
260 	} else {
261 		send_sound(sdp, paula_sndbuffer);
262 	}
263 }
264 
265 /* Try to determine whether sound is available. */
setup_sound(void)266 int setup_sound (void)
267 {
268     sound_available = 1;
269     return 1;
270 }
271 
open_sound(void)272 static int open_sound (void)
273 {
274     if (!currprefs.produce_sound) {
275         return 0;
276     }
277     config_changed = 1;
278 
279     clearbuffer();
280 
281     currprefs.sound_stereo = 1;
282     //currprefs.sound_freq = fs_emu_get_audio_frequency();
283     //changed_prefs.sound_freq = sdp->obtainedfreq;
284 
285     //init_sound_table16 ();
286     sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler;
287 
288     //obtainedfreq = currprefs.sound_freq;
289     obtainedfreq = sdp->obtainedfreq;
290 
291     have_sound = 1;
292     sound_available = 1;
293     paula_sndbufsize = g_audio_buffer_size;
294     paula_sndbufpt = paula_sndbuffer;
295 #ifdef DRIVESOUND
296     driveclick_init();
297 #endif
298     write_log("open_sound returning 1\n");
299     return 1;
300 }
301 
close_sound(void)302 void close_sound (void)
303 {
304     config_changed = 1;
305     gui_data.sndbuf = 0;
306     gui_data.sndbuf_status = 3;
307     if (!have_sound)
308         return;
309 
310     // SDL_PauseAudio (1);
311     clearbuffer();
312     have_sound = 0;
313 }
314 
init_sound(void)315 int init_sound (void)
316 {
317     write_log("init_sound\n");
318     gui_data.sndbuf_status = 3;
319     gui_data.sndbuf = 0;
320     if (!sound_available)
321         return 0;
322     if (currprefs.produce_sound <= 1)
323         return 0;
324     if (have_sound)
325         return 1;
326     if (!open_sound ())
327         return 0;
328     //sdp->paused = 1;
329 #ifdef DRIVESOUND
330     driveclick_reset ();
331 #endif
332     //reset_sound ();
333     //resume_sound ();
334     return 1;
335 }
336 
pause_sound(void)337 void pause_sound (void)
338 {
339     write_log("STUB: pause_sound\n");
340     if (!have_sound)
341         return;
342 #if 0
343     SDL_PauseAudio (1);
344 #endif
345 }
346 
resume_sound(void)347 void resume_sound (void)
348 {
349     write_log("STUB: resume_sound\n");
350     if (!have_sound)
351         return;
352     clearbuffer();
353 #if 0
354     SDL_PauseAudio (0);
355 #endif
356 }
357 
reset_sound(void)358 void reset_sound (void)
359 {
360     clearbuffer();
361     return;
362 }
363 
sound_volume(int dir)364 void sound_volume (int dir)
365 {
366 
367 }
368 
pause_sound_buffer(void)369 void pause_sound_buffer (void)
370 {
371     if (g_audio_callback) {
372         g_audio_callback(1, NULL, 0);
373     }
374 }
375 
restart_sound_buffer(void)376 void restart_sound_buffer(void)
377 {
378     if (g_audio_callback) {
379         g_audio_callback(2, NULL, 0);
380     }
381 }
382 
master_sound_volume(int dir)383 void master_sound_volume (int dir)
384 {
385     STUB("");
386 #if 0
387     int vol, mute, r;
388 
389     r = get_master_volume (&vol, &mute);
390     if (!r)
391             return;
392     if (dir == 0)
393             mute = mute ? 0 : 1;
394     vol += dir * (65536 / 10);
395     if (vol < 0)
396             vol = 0;
397     if (vol > 65535)
398             vol = 65535;
399     aset_master_volume (vol, mute);
400     config_changed = 1;
401 #endif
402 }
403 
sound_mute(int newmute)404 void sound_mute(int newmute)
405 {
406     write_log("STUB: sound_mute\n");
407 }
408