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