Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
audio65.c
Go to the documentation of this file.
1 /* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2021 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 #define SID_USES_LOCK
20 #define OPL_USES_LOCK
21 #define NEED_SID_H
22 //#define CORRUPTION_DEBUG
23 
24 #include "xemu/emutools.h"
25 #include "xemu/opl3.h"
26 #include "audio65.h"
27 // For D7XX (audio DMA):
28 #include "io_mapper.h"
29 // For accessing memory (audio DMA):
30 #include "memory_mapper.h"
31 #include "configdb.h"
32 
33 
36 
38 
39 static opl3_chip opl3;
40 
41 static SDL_AudioDeviceID audio = 0; // SDL audio device
42 static int stereo_separation_orig = 100;
43 static int stereo_separation_other = 0;
44 static int system_sound_mix_freq; // playback sample rate (in Hz) of the emulator itself
45 static int system_sid_cycles_per_sec;
46 static double dma_audio_mixing_value;
47 
48 
49 #if NUMBER_OF_SIDS != 4
50 # error "Currently NUMBER_OF_SIDS macro must be set to 4!"
51 #endif
52 
53 // --- choose one only, normally you want the last (no debug), especially in RELEASEs. Debugging is spammy and expensive in CPU time! ---
54 //#define DEBUG_AUDIO_LOCKS(...) DEBUGPRINT(__VA_ARGS__)
55 //#define DEBUG_AUDIO_LOCKS(...) DEBUG(__VA_ARGS__)
56 #define DEBUG_AUDIO_LOCKS(...)
57 
58 
59 #ifdef OPL_USES_LOCK
60 static SDL_SpinLock opl3_lock;
61 static XEMU_INLINE void LOCK_OPL ( const char *m )
62 {
63  DEBUG_AUDIO_LOCKS("%s: Waiting for OPL3 lock (%d)" NL, m, opl3_lock);
64  SDL_AtomicLock(&opl3_lock);
65  DEBUG_AUDIO_LOCKS("%s: Got OPL3 lock (%d)" NL, m, opl3_lock);
66 }
67 static XEMU_INLINE void UNLOCK_OPL ( const char *m )
68 {
69  SDL_AtomicUnlock(&opl3_lock);
70  DEBUG_AUDIO_LOCKS("%s: Released OPL3 lock (%d)" NL, m, opl3_lock);
71 }
72 #else
73 # define LOCK_OPL(m)
74 # define UNLOCK_OPL(m)
75 # warning "Disabled LOCK for OPL3, you may experience Xemu crashes and/or sound anomalies!"
76 #endif
77 
78 
79 #ifdef SID_USES_LOCK
80 static XEMU_INLINE void LOCK_SID ( const char *m, const int i )
81 {
82  DEBUG_AUDIO_LOCKS("%s: Waiting for SID#%d lock (%d)" NL, m, i, sid[i].spinlock);
83  SDL_AtomicLock(&sid[i].spinlock);
84  DEBUG_AUDIO_LOCKS("%s: Got SID#%d lock (%d)" NL, m, i, sid[i].spinlock);
85 }
86 static XEMU_INLINE void UNLOCK_SID ( const char *m, const int i )
87 {
88  SDL_AtomicUnlock(&sid[i].spinlock);
89  DEBUG_AUDIO_LOCKS("%s: Released SID#%d lock (%d)" NL, m, i, sid[i].spinlock);
90 }
91 #else
92 # define LOCK_SID(m,i)
93 # define UNLOCK_SID(m,i)
94 # warning "Disabled LOCK for SID, you may experience Xemu crashes and/or sound anomalies!"
95 #endif
96 
97 
98 void audio65_sid_write ( const int addr, const Uint8 data )
99 {
100  // SIDs are separated by $20 bytes from each others, 4 SIDs (0-3), instance number
101  // figured out from address
102  const int instance = (addr >> 5) & 3;
103  LOCK_SID("WRITER", instance);
104  sid_write_reg(&sid[instance], addr & 0x1F, data);
105  UNLOCK_SID("WRITER", instance);
106 }
107 
108 
110 {
112  return;
113  LOCK_OPL("WRITER");
114  //OPL3_WriteReg(&opl3, reg, data);
115  OPL3_WriteRegBuffered(&opl3, reg, data);
116  UNLOCK_OPL("WRITER");
117 }
118 
119 
121 {
122  for (int i = 0; i < NUMBER_OF_SIDS; i++) {
123  LOCK_SID("INCER", i);
124  sid[i].sFrameCount++;
125  UNLOCK_SID("INCER", i);
126  }
127 }
128 
129 
130 #ifdef AUDIO_EMULATION
131 static inline void render_dma_audio ( int channel, Sint16 *buffer, int len )
132 {
133  static Sint16 sample[4]; // current sample values of the four channels, normalized to 16 bit signed value
134  static double rate_counter[4] = {0,0,0,0};
135  Uint8 *chio = D7XX + 0x20 + channel * 0x10;
136  unsigned int addr = chio[0xA] + (chio[0xB] << 8) + (chio[0xC] << 16);
137  const Uint16 limit = chio[0x7] + (chio[0x8] << 8);
138  const double rate_step =
139  (double)(chio[4] + (chio[5] << 8) + (chio[6] << 16)) // this value is added to the 24 bit counter every 40.5MHz clock, to see overflow
140  *
141  dma_audio_mixing_value;
142  // convert unsigned -> signed, as Xemu's output is signed, but source sample is unsigned
143  // value of zero does not convert, 0x8000 adds 0x8000 thus doing the crude conversion
144  // (which is the same as XOR in our case). See later when this sample_signedness_conversion value is used.
145  const Uint16 sample_signedness_conversion = (chio[0] & 0x20) << 10;
146 #if 0
147  if (sample_signedness_conversion)
148  DEBUGPRINT("AUDIOCONV-ch%d!", channel);
149 #endif
150  for (unsigned int i = 0; i < len; i++) {
151  if (!(chio[0] & 0x80) || (chio[0] & 0x08)) {
152  // silence
153  sample[channel] = 0;
154  rate_counter[channel] = 0;
155  buffer[i] = 0;
156  continue;
157  }
158  rate_counter[channel] += rate_step;
159  // the reason for while loop: real MEGA65 would not do this, but mixing frequency of audio on typical
160  // PC is low (~44-48KHz) compared to the native MEGA65 40.5MHz clock. Thus in some cases we need more steps
161  // within a single point. Surely it can be optimized a better way, but for now ...
162  while (rate_counter[channel] >= 0x1000000) {
163  rate_counter[channel] -= 0x1000000;
164  if (XEMU_UNLIKELY(addr >= (sizeof(main_ram) - 1))) { // do not overflow fast RAM, as DMA audio can do 24 bit, but fast RAM is much smaller
165  sample[channel] = 0;
166  addr += ((chio[0] & 3) == 3) ? 2 : 1;
167  } else {
168  Uint16 unsigned_read;
169  switch (chio[0] & 3) {
170  case 0: // lower nybble only
171  unsigned_read = (main_ram[addr] & 0x0F) << 12;
172  addr++;
173  break;
174  case 1: // high nybble only
175  unsigned_read = (main_ram[addr] & 0xF0) << 8;
176  addr++;
177  break;
178  case 2: // 8 bit sample
179  unsigned_read = main_ram[addr] << 8;
180  addr++;
181  break;
182  case 3: // 16 bit sample
183  unsigned_read = main_ram[addr] + (main_ram[addr + 1] << 8);
184  addr += 2;
185  break;
186  default:
188  }
189  // do the conversion if needed between signed and unsigned (based on value of sample_signedness_conversion_add)
190  const Sint16 signed_sample = (Uint16)(unsigned_read ^ sample_signedness_conversion);
191  // the final sample value, correcting with the sound setting (FIXME: I am really not sure, if volume is supposed to be linear ...)
192  sample[channel] = ((int)signed_sample * chio[9]) / 0xFF; // volume control (max volume is $FF)
193  }
194  if (XEMU_UNLIKELY((addr & 0xFFFF) == limit)) {
195  // if top address is reached: either stop, or loop (on looped samples only!)
196  if ((chio[0] & 0x40)) {
197  addr = chio[1] + (chio[2] << 8) + (chio[3] << 16); // looping, set address to the begin address
198  } else {
199  chio[0] |= 8; // no loop, stop!
200  sample[channel] = 0;
201  rate_counter[channel] = 0;
202  break;
203  }
204  }
205  }
206  // render one sample for this channel to the buffer
207  buffer[i] = sample[channel];
208  }
209  // End of loop:
210  // write back address ...
211  chio[0xA] = addr & 0xFF;
212  chio[0xB] = (addr >> 8) & 0xFF;
213  chio[0xC] = (addr >> 16) & 0xFF;
214 }
215 
216 
217 void audio_set_stereo_parameters ( int vol, int sep )
218 {
219  if (sep == AUDIO_UNCHANGED_SEPARATION) {
220  sep = stereo_separation;
221  } else {
222  if (sep > 100)
223  sep = 100;
224  else if (sep < -100)
225  sep = -100;
226  stereo_separation = sep;
227  }
228  if (vol == AUDIO_UNCHANGED_VOLUME) {
229  vol = audio_volume;
230  } else {
231  if (vol > 100)
232  vol = 100;
233  else if (vol < 0)
234  vol = 0;
235  audio_volume = vol;
236  }
237  //sep = ((sep + 100) * 0x100) / 200;
238  sep = (sep + 100) / 2;
239  //sep = (sep + 100) * 0x100 / 200;
240  stereo_separation_orig = (sep * vol) / 100;
241  stereo_separation_other = ((100 - sep) * vol) / 100;
242  DEBUGPRINT("AUDIO: volume is set to %d%%, stereo separation is %d%% [component-A is %d, component-B is %d]" NL, audio_volume, stereo_separation, stereo_separation_orig, stereo_separation_other);
243 }
244 
245 
246 // 10 channels, consist of: 4 channel for audio DMA, 4 channel for SIDs (each SIDs are pre-mixed to one channel by sid.c), 2 OPL3 channel (OPL3 is pre-mixed into two channels in opl3.c)
247 #define MIXED_CHANNELS 10
248 
249 #ifdef CORRUPTION_DEBUG
250 # define EXTRA_STREAM_CHANNELS 99
251 #else
252 # define EXTRA_STREAM_CHANNELS 0
253 #endif
254 
255 #define STREAMS_SIZE_ALL (((MIXED_CHANNELS) + (EXTRA_STREAM_CHANNELS)) * (AUDIO_BUFFER_SAMPLES_MAX))
256 #define STREAMS(n) (streams + ((n) * (AUDIO_BUFFER_SAMPLES_MAX)))
257 #define STREAMS_SAMPLE(n,d) ((int)(STREAMS(n)[d]))
258 
259 
260 static void audio_callback ( void *userdata, Uint8 *stereo_out_stream, int len )
261 {
262  static Sint16 streams[STREAMS_SIZE_ALL];
263  static int nosound_previous = -1;
264  if (XEMU_UNLIKELY(nosound_previous != configdb.nosound)) {
265  nosound_previous = configdb.nosound;
266  DEBUGPRINT("AUDIO: callback switches to %s mode." NL, configdb.nosound ? "silent" : "working");
267  }
269  // Render silence ...
270  // Here we use "len" as-is, since it's before the shift operation below, and means BYTES, what SDL is asking from us
271  memset(stereo_out_stream, 0, len);
272  return;
273  }
274  //DEBUGPRINT("AUDIO: audio callback, wants %d bytes to be rendered" NL, len);
275  len >>= 2; // the size in *SAMPLES* (not in bytes) is /4, since it's a stereo stream, and 2 bytes/sample, we want to render
276  //DEBUGPRINT("AUDIO: audio callback, wants %d samples to be rendered" NL, len);
279  DEBUGPRINT("AUDIO: ERROR, SDL wants more samples (%d) than buffer size (%d)!" NL, len, AUDIO_BUFFER_SAMPLES_MAX);
280  }
281  // Render samples from the four audio DMA units
282  for (int i = 0; i < 4; i++)
283  render_dma_audio(i, STREAMS(i), len);
284  // Render samples from the four SIDs
285  for (int i = 0; i < NUMBER_OF_SIDS; i++) {
286  if (XEMU_UNLIKELY(!(configdb.sidmask & (1 << i)))) {
287  memset(STREAMS(4 + i), 0, len * sizeof(Sint16));
288  continue;
289  }
290  LOCK_SID("RENDER", i);
291  sid_render(&sid[i], STREAMS(4 + i), len, 1);
292  UNLOCK_SID("RENDER", i);
293  }
294  // Render samples for the OPL3 emulation
295  if (XEMU_LIKELY(!configdb.noopl3)) {
296  LOCK_OPL("RENDER");
297  OPL3_GenerateStream(&opl3, STREAMS(8), STREAMS(9), len, 1, 1);
298  UNLOCK_OPL("RENDER");
299  } else {
300  memset(STREAMS(8), 0, len * sizeof(Sint16));
301  memset(STREAMS(9), 0, len * sizeof(Sint16));
302  }
303  // Now mix the result ...
304  for (int i = 0, j = 0; i < len; i++) {
305  // mixing streams together
306  // Currently: put the first two SIDS to the left, the second two to the right, same for DMA audio channels, and OPL3 seems to need 2 channel
307  const register int orig_left = STREAMS_SAMPLE(0, i) + STREAMS_SAMPLE(1, i) + STREAMS_SAMPLE(4, i) + STREAMS_SAMPLE(5, i) + STREAMS_SAMPLE(8, i);
308  const register int orig_right = STREAMS_SAMPLE(2, i) + STREAMS_SAMPLE(3, i) + STREAMS_SAMPLE(6, i) + STREAMS_SAMPLE(7, i) + STREAMS_SAMPLE(9, i);
309 #if 1
310  // channel stereo separation (including inversion) + volume handling
311  int left = ((orig_left * stereo_separation_orig) / 100) + ((orig_right * stereo_separation_other) / 100);
312  int right = ((orig_right * stereo_separation_orig) / 100) + ((orig_left * stereo_separation_other) / 100);
313 #else
314  int left = orig_left;
315  int right = orig_right;
316 #endif
317  // do some ugly clipping ...
318  if (left > 0x7FFF) left = 0x7FFF;
319  else if (left < -0x8000) left = -0x8000;
320  if (right > 0x7FFF) right = 0x7FFF;
321  else if (right < -0x8000) right = -0x8000;
322  // write the output stereo stream for SDL (it's an interlaved left-right-left-right kind of thing)
323  ((Sint16*)stereo_out_stream)[j++] = left;
324  ((Sint16*)stereo_out_stream)[j++] = right;
325  }
326 #ifdef CORRUPTION_DEBUG
327 # warning "You have CORRUPTION_DEBUG enabled"
328  for (Sint16 *p = STREAMS(MIXED_CHANNELS); p < streams + STREAMS_SIZE_ALL; p++) {
329  if (*p)
330  DEBUGPRINT("AUDIO BUFFER CORRUPTION AT OFFSET: %d" NL, (int)(p - STREAMS(0)));
331  }
332 #endif
333 }
334 #endif
335 
336 
337 
338 void audio65_clear_regs ( void )
339 {
340  // OPL and SIDs lock are implemented by the ..._write() function, no need to take care here
341  for (int i = 0; i < 0x100; i++)
342  audio65_opl3_write(i, 0);
343  for (int i = 0; i < NUMBER_OF_SIDS * 0x20; i++)
344  audio65_sid_write(i << i, 0);
345  memset(D7XX + 0x20, 0, 0x40); // DMA audio related registers
346  DEBUGPRINT("AUDIO: clearing audio related registers." NL);
347 }
348 
349 
350 void audio65_reset ( void )
351 {
352  // We always initialize SIDs/OPL, even if no audio emulation is compiled in
353  // Since there can be problem to write SID registers otherwise?
354  for (int i = 0; i < NUMBER_OF_SIDS; i++) {
355  LOCK_SID("RESET", i);
356  sid_init(&sid[i], system_sid_cycles_per_sec, system_sound_mix_freq);
357  UNLOCK_SID("RESET", i);
358  }
359  LOCK_OPL("RESET");
360  OPL3_Reset(&opl3, system_sound_mix_freq);
361  UNLOCK_OPL("RESET");
362  DEBUGPRINT("AUDIO: reset for %d SIDs (%d cycles per sec) and 1 OPL3 chip for %dHz sampling rate." NL, NUMBER_OF_SIDS, system_sid_cycles_per_sec, system_sound_mix_freq);
364 }
365 
366 
367 void audio65_start ( void )
368 {
369  static volatile int started = 0;
370  if (started) {
371  ERROR_WINDOW("Trying to restart audio??\nRefuseing to do so!!");
372  return;
373  }
374  started = 1;
375  if (!audio)
376  return;
377  DEBUGPRINT("AUDIO: start mixing." NL);
378  SDL_PauseAudioDevice(audio, 0);
379 }
380 
381 
382 void audio65_init ( int sid_cycles_per_sec, int sound_mix_freq, int volume, int separation, unsigned int buffer_size )
383 {
384  static volatile int initialized = 0;
385  if (initialized) {
386  ERROR_WINDOW("Trying to reinitialize audio??\nRefusing to do so!!");
387  return;
388  }
389  initialized = 1;
390  for (int i = 0; i < NUMBER_OF_SIDS; i++)
391  UNLOCK_SID("INIT", i);
392  UNLOCK_OPL("INIT");
393  system_sound_mix_freq = sound_mix_freq;
394  system_sid_cycles_per_sec = sid_cycles_per_sec;
395  audio65_reset();
396 #ifdef AUDIO_EMULATION
397  dma_audio_mixing_value = (double)40500000.0 / (double)sound_mix_freq; // ... but with Xemu we use a much lower sampling rate, thus compensate (will fail on samples, rate >= xemu_mixing_rate ...)
398  SDL_AudioSpec audio_want, audio_got;
399  SDL_memset(&audio_want, 0, sizeof(audio_want));
400  audio_want.freq = sound_mix_freq;
401  audio_want.format = AUDIO_S16SYS; // used format by SID emulation (ie: signed short, with native endianness)
402  audio_want.channels = 2; // that is: stereo, for the two SIDs
403  audio_want.samples = buffer_size; // Sample size suggested (?) for the callback to render once
404  audio_want.callback = audio_callback; // Audio render callback function, called periodically by SDL on demand
405  audio_want.userdata = NULL; // Not used, "userdata" parameter passed to the callback by SDL
406  if (audio)
407  ERROR_WINDOW("audio was not zero before calling SDL_OpenAudioDevice!");
408  audio = SDL_OpenAudioDevice(NULL, 0, &audio_want, &audio_got, 0);
409  if (audio) {
410  for (int i = 0; i < SDL_GetNumAudioDevices(0); i++)
411  DEBUG("AUDIO: audio device is #%d: %s" NL, i, SDL_GetAudioDeviceName(i, 0));
412  // Sanity check that we really got the same audio specification we wanted
413  if (audio_want.freq != audio_got.freq || audio_want.format != audio_got.format || audio_want.channels != audio_got.channels || audio_got.samples > AUDIO_BUFFER_SAMPLES_MAX) {
414  SDL_CloseAudioDevice(audio); // forget audio, if it's not our expected format :(
415  audio = 0;
416  ERROR_WINDOW("Audio parameter mismatches.");
417  }
418  DEBUGPRINT("AUDIO: initialized (#%d), %d Hz, %d channels, %d buffer sample size." NL, audio, audio_got.freq, audio_got.channels, audio_got.samples);
419  //if (audio) {
420  // DEBUGPRINT("AUDIO: !!!!!!!!!!! sample size = %d" NL, audio_got.samples);
421  //}
422  } else
423  ERROR_WINDOW("Cannot open audio device!");
424  audio_set_stereo_parameters(volume, separation);
425 #else
426  DEBUGPRINT("AUDIO: has been disabled at compilation time." NL);
427 #endif
428 }
sid_render
void sid_render(struct SidEmulation *sidemu, short *buffer, unsigned long len, int step)
Definition: sid.c:256
AUDIO_DEFAULT_VOLUME
#define AUDIO_DEFAULT_VOLUME
Definition: audio65.h:37
configdb.h
stereo_separation
int stereo_separation
Definition: audio65.c:34
emutools.h
STREAMS_SIZE_ALL
#define STREAMS_SIZE_ALL
Definition: audio65.c:255
STREAMS_SAMPLE
#define STREAMS_SAMPLE(n, d)
Definition: audio65.c:257
audio65_init
void audio65_init(int sid_cycles_per_sec, int sound_mix_freq, int volume, int separation, unsigned int buffer_size)
Definition: audio65.c:382
OPL3_GenerateStream
void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples, const uint32_t increment1, const uint32_t increment2)
Definition: opl3.c:1372
audio65_start
void audio65_start(void)
Definition: audio65.c:367
STREAMS
#define STREAMS(n)
Definition: audio65.c:256
AUDIO_DEFAULT_SEPARATION
#define AUDIO_DEFAULT_SEPARATION
Definition: audio65.h:36
configdb_st::sidmask
int sidmask
Definition: configdb.h:104
io_mapper.h
addr
int addr
Definition: dma65.c:81
XEMU_INLINE
#define XEMU_INLINE
Definition: emutools_basicdefs.h:126
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
AUDIO_UNCHANGED_SEPARATION
#define AUDIO_UNCHANGED_SEPARATION
Definition: audio65.h:38
Uint8
uint8_t Uint8
Definition: fat32.c:51
audio65_opl3_write
void audio65_opl3_write(Uint8 reg, Uint8 data)
Definition: audio65.c:109
main_ram
Uint8 main_ram[512<< 10]
Definition: memory_mapper.c:47
audio65_reset
void audio65_reset(void)
Definition: audio65.c:350
sid
struct SidEmulation sid[NUMBER_OF_SIDS]
Definition: audio65.c:37
opl3.h
audio_volume
int audio_volume
Definition: audio65.c:35
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
SidEmulation::spinlock
SDL_SpinLock spinlock
Definition: sid.h:148
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
memory_mapper.h
AUDIO_UNCHANGED_VOLUME
#define AUDIO_UNCHANGED_VOLUME
Definition: audio65.h:39
XEMU_LIKELY
#define XEMU_LIKELY(__x__)
Definition: emutools_basicdefs.h:124
instance
int instance
Definition: primo.c:89
NL
#define NL
Definition: fat32.c:37
configdb
struct configdb_st configdb
Definition: configdb.c:34
sid_write_reg
void sid_write_reg(struct SidEmulation *sidemu, int reg, unsigned char val)
Definition: sid.c:513
OPL3_Reset
void OPL3_Reset(opl3_chip *chip, uint32_t samplerate)
Definition: opl3.c:1198
DEBUG_AUDIO_LOCKS
#define DEBUG_AUDIO_LOCKS(...)
Definition: audio65.c:56
_opl3_chip
Definition: opl3.h:99
audio_set_stereo_parameters
void audio_set_stereo_parameters(int vol, int sep)
Definition: audio65.c:217
NUMBER_OF_SIDS
#define NUMBER_OF_SIDS
Definition: audio65.h:22
audio65_clear_regs
void audio65_clear_regs(void)
Definition: audio65.c:338
MIXED_CHANNELS
#define MIXED_CHANNELS
Definition: audio65.c:247
audio65_sid_inc_framecount
void audio65_sid_inc_framecount(void)
Definition: audio65.c:120
audio65_sid_write
void audio65_sid_write(const int addr, const Uint8 data)
Definition: audio65.c:98
sid_init
void sid_init(struct SidEmulation *sidemu, unsigned long cyclesPerSec, unsigned long mixfrq)
Definition: sid.c:649
Uint16
uint16_t Uint16
Definition: fat32.c:50
OPL3_WriteRegBuffered
void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v)
Definition: opl3.c:1344
XEMU_UNREACHABLE
#define XEMU_UNREACHABLE()
Definition: emutools_basicdefs.h:127
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
configdb_st::noopl3
int noopl3
Definition: configdb.h:103
AUDIO_BUFFER_SAMPLES_MAX
#define AUDIO_BUFFER_SAMPLES_MAX
Definition: audio65.h:25
D7XX
Uint8 D7XX[0x100]
Definition: io_mapper.c:39
SidEmulation::sFrameCount
int sFrameCount
Definition: sid.h:79
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
audio65.h
configdb_st::nosound
int nosound
Definition: configdb.h:102
SidEmulation
Definition: sid.h:78