pokeysnd.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:36k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * pokeysnd.c - POKEY sound chip emulation, v2.4
  3.  *
  4.  * Copyright (C) 1996-1998 Ron Fries
  5.  * Copyright (C) 1998-2006 Atari800 development team (see DOC/CREDITS)
  6.  *
  7.  * This file is part of the Atari800 emulator project which emulates
  8.  * the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
  9.  *
  10.  * Atari800 is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * Atari800 is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with Atari800; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23. */
  24. #include "config.h"
  25. #ifdef ASAP /* external project, see http://asap.sf.net */
  26. #include "asap_internal.h"
  27. #else
  28. #include "atari.h"
  29. #ifndef __PLUS
  30. #include "sndsave.h"
  31. #else
  32. #include "sound_win.h"
  33. #endif
  34. #endif
  35. #include "mzpokeysnd.h"
  36. #include "pokeysnd.h"
  37. #ifdef WORDS_UNALIGNED_OK
  38. #  define READ_U32(x)     (*(uint32 *) (x))
  39. #  define WRITE_U32(x, d) (*(uint32 *) (x) = (d))
  40. #else
  41. #  ifdef WORDS_BIGENDIAN
  42. #    define READ_U32(x) (((*(unsigned char *)(x)) << 24) | ((*((unsigned char *)(x) + 1)) << 16) | 
  43.                         ((*((unsigned char *)(x) + 2)) << 8) | ((*((unsigned char *)(x) + 3))))
  44. #    define WRITE_U32(x, d) 
  45.   { 
  46.   uint32 i = d; 
  47.   (*(unsigned char *) (x)) = (((i) >> 24) & 255); 
  48.   (*((unsigned char *) (x) + 1)) = (((i) >> 16) & 255); 
  49.   (*((unsigned char *) (x) + 2)) = (((i) >> 8) & 255); 
  50.   (*((unsigned char *) (x) + 3)) = ((i) & 255); 
  51.   }
  52. #  else
  53. #    define READ_U32(x) ((*(unsigned char *) (x)) | ((*((unsigned char *) (x) + 1)) << 8) | 
  54.                         ((*((unsigned char *) (x) + 2)) << 16) | ((*((unsigned char *) (x) + 3)) << 24))
  55. #    define WRITE_U32(x, d) 
  56.   { 
  57.   uint32 i = d; 
  58.   (*(unsigned char *)(x)) = ((i) & 255); 
  59.   (*((unsigned char *)(x) + 1)) = (((i) >> 8) & 255); 
  60.   (*((unsigned char *)(x) + 2)) = (((i) >> 16) & 255); 
  61.   (*((unsigned char *)(x) + 3)) = (((i) >> 24) & 255); 
  62.   }
  63. #  endif
  64. #endif
  65. /* GLOBAL VARIABLE DEFINITIONS */
  66. /* number of pokey chips currently emulated */
  67. static uint8 Num_pokeys;
  68. static uint8 AUDV[4 * MAXPOKEYS]; /* Channel volume - derived */
  69. static uint8 Outbit[4 * MAXPOKEYS]; /* current state of the output (high or low) */
  70. static uint8 Outvol[4 * MAXPOKEYS]; /* last output volume for each channel */
  71. /* Initialze the bit patterns for the polynomials. */
  72. /* The 4bit and 5bit patterns are the identical ones used in the pokey chip. */
  73. /* Though the patterns could be packed with 8 bits per byte, using only a */
  74. /* single bit per byte keeps the math simple, which is important for */
  75. /* efficient processing. */
  76. static uint8 bit4[POLY4_SIZE] =
  77. #ifndef POKEY23_POLY
  78. {1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0}; /* new table invented by Perry */
  79. #else
  80. {1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}; /* original POKEY 2.3 table */
  81. #endif
  82. static uint8 bit5[POLY5_SIZE] =
  83. #ifndef POKEY23_POLY
  84. {1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0};
  85. #else
  86. {0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1};
  87. #endif
  88. static uint32 P4 = 0, /* Global position pointer for the 4-bit  POLY array */
  89.  P5 = 0, /* Global position pointer for the 5-bit  POLY array */
  90.  P9 = 0, /* Global position pointer for the 9-bit  POLY array */
  91.  P17 = 0; /* Global position pointer for the 17-bit POLY array */
  92. static uint32 Div_n_cnt[4 * MAXPOKEYS], /* Divide by n counter. one for each channel */
  93.  Div_n_max[4 * MAXPOKEYS]; /* Divide by n maximum, one for each channel */
  94. static uint32 Samp_n_max, /* Sample max.  For accuracy, it is *256 */
  95.  Samp_n_cnt[2]; /* Sample cnt. */
  96. extern int atari_speaker;
  97. #ifdef INTERPOLATE_SOUND
  98. static uint16 last_val = 0; /* last output value */
  99. #ifdef STEREO_SOUND
  100. static uint16 last_val2 = 0; /* last output value */
  101. #endif
  102. #endif
  103. /* Volume only emulations declarations */
  104. #ifdef VOL_ONLY_SOUND
  105. #define SAMPBUF_MAX 2000
  106. int sampbuf_val[SAMPBUF_MAX]; /* volume values */
  107. int sampbuf_cnt[SAMPBUF_MAX]; /* relative start time */
  108. int sampbuf_ptr = 0; /* pointer to sampbuf */
  109. int sampbuf_rptr = 0; /* pointer to read from sampbuf */
  110. int sampbuf_last = 0; /* last absolute time */
  111. int sampbuf_AUDV[4 * MAXPOKEYS]; /* prev. channel volume */
  112. int sampbuf_lastval = 0; /* last volume */
  113. int sampout; /* last out volume */
  114. uint16 samp_freq;
  115. int samp_consol_val = 0; /* actual value of console sound */
  116. #ifdef STEREO_SOUND
  117. int sampbuf_val2[SAMPBUF_MAX]; /* volume values */
  118. int sampbuf_cnt2[SAMPBUF_MAX]; /* relative start time */
  119. int sampbuf_ptr2 = 0; /* pointer to sampbuf */
  120. int sampbuf_rptr2 = 0; /* pointer to read from sampbuf */
  121. int sampbuf_last2 = 0; /* last absolute time */
  122. int sampbuf_lastval2 = 0; /* last volume */
  123. int sampout2; /* last out volume */
  124. #endif
  125. #endif  /* VOL_ONLY_SOUND */
  126. static uint32 snd_freq17 = FREQ_17_EXACT;
  127. int32 snd_playback_freq = 44100;
  128. uint8 snd_num_pokeys = 1;
  129. static int snd_flags = 0;
  130. static int mz_quality = 0; /* default quality for mzpokeysnd */
  131. #ifdef __PLUS
  132. int mz_clear_regs = 0;
  133. #endif
  134. int enable_new_pokey = TRUE;
  135. #ifndef ASAP
  136. int stereo_enabled = FALSE;
  137. #endif
  138. /* multiple sound engine interface */
  139. static void Pokey_process_8(void *sndbuffer, unsigned sndn);
  140. static void Pokey_process_16(void *sndbuffer, unsigned sndn);
  141. static void null_pokey_process(void *sndbuffer, unsigned int sndn) {}
  142. void (*Pokey_process_ptr)(void *sndbuffer, unsigned int sndn) = null_pokey_process;
  143. static void Update_pokey_sound_rf(uint16, uint8, uint8, uint8);
  144. static void null_pokey_sound(uint16 addr, uint8 val, uint8 chip, uint8 gain) {}
  145. void (*Update_pokey_sound) (uint16 addr, uint8 val, uint8 chip, uint8 gain)
  146.   = null_pokey_sound;
  147. #ifdef SERIO_SOUND
  148. static void Update_serio_sound_rf(int out, UBYTE data);
  149. static void null_serio_sound(int out, UBYTE data) {}
  150. void (*Update_serio_sound)(int out, UBYTE data) = null_serio_sound;
  151. int serio_sound_enabled = 1;
  152. #endif
  153. #ifdef CONSOLE_SOUND
  154. static void Update_consol_sound_rf(int set);
  155. static void null_consol_sound(int set) {}
  156. void (*Update_consol_sound)(int set) = null_consol_sound;
  157. int console_sound_enabled = 1;
  158. #endif
  159. #ifdef VOL_ONLY_SOUND
  160. static void Update_vol_only_sound_rf(void);
  161. static void null_vol_only_sound(void) {}
  162. void (*Update_vol_only_sound)(void) = null_vol_only_sound;
  163. #endif
  164. /*****************************************************************************/
  165. /* In my routines, I treat the sample output as another divide by N counter  */
  166. /* For better accuracy, the Samp_n_cnt has a fixed binary decimal point      */
  167. /* which has 8 binary digits to the right of the decimal point.  I use a two */
  168. /* byte array to give me a minimum of 40 bits, and then use pointer math to  */
  169. /* reference either the 24.8 whole/fraction combination or the 32-bit whole  */
  170. /* only number.  This is mainly used to keep the math simple for             */
  171. /* optimization. See below:                                                  */
  172. /*                                                                           */
  173. /* Representation on little-endian machines:                                 */
  174. /* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx */
  175. /* fraction   whole    whole    whole      whole   unused   unused   unused  */
  176. /*                                                                           */
  177. /* Samp_n_cnt[0] gives me a 32-bit int 24 whole bits with 8 fractional bits, */
  178. /* while (uint32 *)((uint8 *)(&Samp_n_cnt[0])+1) gives me the 32-bit whole   */
  179. /* number only.                                                              */
  180. /*                                                                           */
  181. /* Representation on big-endian machines:                                    */
  182. /* xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | xxxxxxxx xxxxxxxx xxxxxxxx.xxxxxxxx */
  183. /*  unused   unused   unused    whole      whole    whole    whole  fraction */
  184. /*                                                                           */
  185. /* Samp_n_cnt[1] gives me a 32-bit int 24 whole bits with 8 fractional bits, */
  186. /* while (uint32 *)((uint8 *)(&Samp_n_cnt[0])+3) gives me the 32-bit whole   */
  187. /* number only.                                                              */
  188. /*****************************************************************************/
  189. /*****************************************************************************/
  190. /* Module:  Pokey_sound_init()                                               */
  191. /* Purpose: to handle the power-up initialization functions                  */
  192. /*          these functions should only be executed on a cold-restart        */
  193. /*                                                                           */
  194. /* Author:  Ron Fries                                                        */
  195. /* Date:    January 1, 1997                                                  */
  196. /*                                                                           */
  197. /* Inputs:  freq17 - the value for the '1.79MHz' Pokey audio clock           */
  198. /*          playback_freq - the playback frequency in samples per second     */
  199. /*          num_pokeys - specifies the number of pokey chips to be emulated  */
  200. /*                                                                           */
  201. /* Outputs: Adjusts local globals - no return value                          */
  202. /*                                                                           */
  203. /*****************************************************************************/
  204. static int Pokey_sound_init_rf(uint32 freq17, uint16 playback_freq,
  205.            uint8 num_pokeys, unsigned int flags);
  206. int Pokey_DoInit(void)
  207. {
  208. if (enable_new_pokey)
  209. return Pokey_sound_init_mz(snd_freq17, (uint16) snd_playback_freq,
  210. snd_num_pokeys, snd_flags, mz_quality
  211. #ifdef __PLUS
  212. , mz_clear_regs
  213. #endif
  214. );
  215. else
  216. return Pokey_sound_init_rf(snd_freq17, (uint16) snd_playback_freq,
  217. snd_num_pokeys, snd_flags);
  218. }
  219. int Pokey_sound_init(uint32 freq17, uint16 playback_freq, uint8 num_pokeys,
  220.                      unsigned int flags
  221. #ifdef __PLUS
  222.                      , int clear_regs
  223. #endif
  224. )
  225. {
  226. snd_freq17 = freq17;
  227. snd_playback_freq = playback_freq;
  228. snd_num_pokeys = num_pokeys;
  229. snd_flags = flags;
  230. #ifdef __PLUS
  231. mz_clear_regs = clear_regs;
  232. #endif
  233. return Pokey_DoInit();
  234. }
  235. void Pokey_set_mzquality(int quality) /* specially for win32, perhaps not needed? */
  236. {
  237. mz_quality = quality;
  238. }
  239. void Pokey_process(void *sndbuffer, unsigned int sndn)
  240. {
  241. Pokey_process_ptr(sndbuffer, sndn);
  242. #if !defined(__PLUS) && !defined(ASAP)
  243. WriteToSoundFile(sndbuffer, sndn);
  244. #endif
  245. }
  246. static int Pokey_sound_init_rf(uint32 freq17, uint16 playback_freq,
  247.            uint8 num_pokeys, unsigned int flags)
  248. {
  249. uint8 chan;
  250. Update_pokey_sound = Update_pokey_sound_rf;
  251. #ifdef SERIO_SOUND
  252. Update_serio_sound = Update_serio_sound_rf;
  253. #endif
  254. #ifdef CONSOLE_SOUND
  255. Update_consol_sound = Update_consol_sound_rf;
  256. #endif
  257. #ifdef VOL_ONLY_SOUND
  258. Update_vol_only_sound = Update_vol_only_sound_rf;
  259. #endif
  260. Pokey_process_ptr = (flags & SND_BIT16) ? Pokey_process_16 : Pokey_process_8;
  261. #ifdef VOL_ONLY_SOUND
  262. samp_freq = playback_freq;
  263. #endif
  264. /* start all of the polynomial counters at zero */
  265. P4 = 0;
  266. P5 = 0;
  267. P9 = 0;
  268. P17 = 0;
  269. /* calculate the sample 'divide by N' value based on the playback freq. */
  270. Samp_n_max = ((uint32) freq17 << 8) / playback_freq;
  271. Samp_n_cnt[0] = 0; /* initialize all bits of the sample */
  272. Samp_n_cnt[1] = 0; /* 'divide by N' counter */
  273. for (chan = 0; chan < (MAXPOKEYS * 4); chan++) {
  274. Outvol[chan] = 0;
  275. Outbit[chan] = 0;
  276. Div_n_cnt[chan] = 0;
  277. Div_n_max[chan] = 0x7fffffffL;
  278. AUDV[chan] = 0;
  279. #ifdef VOL_ONLY_SOUND
  280. sampbuf_AUDV[chan] = 0;
  281. #endif
  282. }
  283. /* set the number of pokey chips currently emulated */
  284. Num_pokeys = num_pokeys;
  285. return 0; /* OK */
  286. }
  287. /*****************************************************************************/
  288. /* Module:  Update_pokey_sound()                                             */
  289. /* Purpose: To process the latest control values stored in the AUDF, AUDC,   */
  290. /*          and AUDCTL registers.  It pre-calculates as much information as  */
  291. /*          possible for better performance.  This routine has not been      */
  292. /*          optimized.                                                       */
  293. /*                                                                           */
  294. /* Author:  Ron Fries                                                        */
  295. /* Date:    January 1, 1997                                                  */
  296. /*                                                                           */
  297. /* Inputs:  addr - the address of the parameter to be changed                */
  298. /*          val - the new value to be placed in the specified address        */
  299. /*          gain - specified as an 8-bit fixed point number - use 1 for no   */
  300. /*                 amplification (output is multiplied by gain)              */
  301. /*                                                                           */
  302. /* Outputs: Adjusts local globals - no return value                          */
  303. /*                                                                           */
  304. /*****************************************************************************/
  305. static void Update_pokey_sound_rf(uint16 addr, uint8 val, uint8 chip,
  306.   uint8 gain)
  307. {
  308. uint32 new_val = 0;
  309. uint8 chan;
  310. uint8 chan_mask;
  311. uint8 chip_offs;
  312. /* calculate the chip_offs for the channel arrays */
  313. chip_offs = chip << 2;
  314. /* determine which address was changed */
  315. switch (addr & 0x0f) {
  316. case _AUDF1:
  317. /* AUDF[CHAN1 + chip_offs] = val; */
  318. chan_mask = 1 << CHAN1;
  319. if (AUDCTL[chip] & CH1_CH2) /* if ch 1&2 tied together */
  320. chan_mask |= 1 << CHAN2; /* then also change on ch2 */
  321. break;
  322. case _AUDC1:
  323. /* AUDC[CHAN1 + chip_offs] = val; */
  324. AUDV[CHAN1 + chip_offs] = (val & VOLUME_MASK) * gain;
  325. chan_mask = 1 << CHAN1;
  326. break;
  327. case _AUDF2:
  328. /* AUDF[CHAN2 + chip_offs] = val; */
  329. chan_mask = 1 << CHAN2;
  330. break;
  331. case _AUDC2:
  332. /* AUDC[CHAN2 + chip_offs] = val; */
  333. AUDV[CHAN2 + chip_offs] = (val & VOLUME_MASK) * gain;
  334. chan_mask = 1 << CHAN2;
  335. break;
  336. case _AUDF3:
  337. /* AUDF[CHAN3 + chip_offs] = val; */
  338. chan_mask = 1 << CHAN3;
  339. if (AUDCTL[chip] & CH3_CH4) /* if ch 3&4 tied together */
  340. chan_mask |= 1 << CHAN4; /* then also change on ch4 */
  341. break;
  342. case _AUDC3:
  343. /* AUDC[CHAN3 + chip_offs] = val; */
  344. AUDV[CHAN3 + chip_offs] = (val & VOLUME_MASK) * gain;
  345. chan_mask = 1 << CHAN3;
  346. break;
  347. case _AUDF4:
  348. /* AUDF[CHAN4 + chip_offs] = val; */
  349. chan_mask = 1 << CHAN4;
  350. break;
  351. case _AUDC4:
  352. /* AUDC[CHAN4 + chip_offs] = val; */
  353. AUDV[CHAN4 + chip_offs] = (val & VOLUME_MASK) * gain;
  354. chan_mask = 1 << CHAN4;
  355. break;
  356. case _AUDCTL:
  357. /* AUDCTL[chip] = val; */
  358. chan_mask = 15; /* all channels */
  359. break;
  360. default:
  361. chan_mask = 0;
  362. break;
  363. }
  364. /************************************************************/
  365. /* As defined in the manual, the exact Div_n_cnt values are */
  366. /* different depending on the frequency and resolution:     */
  367. /*    64 kHz or 15 kHz - AUDF + 1                           */
  368. /*    1 MHz, 8-bit -     AUDF + 4                           */
  369. /*    1 MHz, 16-bit -    AUDF[CHAN1]+256*AUDF[CHAN2] + 7    */
  370. /************************************************************/
  371. /* only reset the channels that have changed */
  372. if (chan_mask & (1 << CHAN1)) {
  373. /* process channel 1 frequency */
  374. if (AUDCTL[chip] & CH1_179)
  375. new_val = AUDF[CHAN1 + chip_offs] + 4;
  376. else
  377. new_val = (AUDF[CHAN1 + chip_offs] + 1) * Base_mult[chip];
  378. if (new_val != Div_n_max[CHAN1 + chip_offs]) {
  379. Div_n_max[CHAN1 + chip_offs] = new_val;
  380. if (Div_n_cnt[CHAN1 + chip_offs] > new_val) {
  381. Div_n_cnt[CHAN1 + chip_offs] = new_val;
  382. }
  383. }
  384. }
  385. if (chan_mask & (1 << CHAN2)) {
  386. /* process channel 2 frequency */
  387. if (AUDCTL[chip] & CH1_CH2) {
  388. if (AUDCTL[chip] & CH1_179)
  389. new_val = AUDF[CHAN2 + chip_offs] * 256 +
  390. AUDF[CHAN1 + chip_offs] + 7;
  391. else
  392. new_val = (AUDF[CHAN2 + chip_offs] * 256 +
  393.    AUDF[CHAN1 + chip_offs] + 1) * Base_mult[chip];
  394. }
  395. else
  396. new_val = (AUDF[CHAN2 + chip_offs] + 1) * Base_mult[chip];
  397. if (new_val != Div_n_max[CHAN2 + chip_offs]) {
  398. Div_n_max[CHAN2 + chip_offs] = new_val;
  399. if (Div_n_cnt[CHAN2 + chip_offs] > new_val) {
  400. Div_n_cnt[CHAN2 + chip_offs] = new_val;
  401. }
  402. }
  403. }
  404. if (chan_mask & (1 << CHAN3)) {
  405. /* process channel 3 frequency */
  406. if (AUDCTL[chip] & CH3_179)
  407. new_val = AUDF[CHAN3 + chip_offs] + 4;
  408. else
  409. new_val = (AUDF[CHAN3 + chip_offs] + 1) * Base_mult[chip];
  410. if (new_val != Div_n_max[CHAN3 + chip_offs]) {
  411. Div_n_max[CHAN3 + chip_offs] = new_val;
  412. if (Div_n_cnt[CHAN3 + chip_offs] > new_val) {
  413. Div_n_cnt[CHAN3 + chip_offs] = new_val;
  414. }
  415. }
  416. }
  417. if (chan_mask & (1 << CHAN4)) {
  418. /* process channel 4 frequency */
  419. if (AUDCTL[chip] & CH3_CH4) {
  420. if (AUDCTL[chip] & CH3_179)
  421. new_val = AUDF[CHAN4 + chip_offs] * 256 +
  422. AUDF[CHAN3 + chip_offs] + 7;
  423. else
  424. new_val = (AUDF[CHAN4 + chip_offs] * 256 +
  425.    AUDF[CHAN3 + chip_offs] + 1) * Base_mult[chip];
  426. }
  427. else
  428. new_val = (AUDF[CHAN4 + chip_offs] + 1) * Base_mult[chip];
  429. if (new_val != Div_n_max[CHAN4 + chip_offs]) {
  430. Div_n_max[CHAN4 + chip_offs] = new_val;
  431. if (Div_n_cnt[CHAN4 + chip_offs] > new_val) {
  432. Div_n_cnt[CHAN4 + chip_offs] = new_val;
  433. }
  434. }
  435. }
  436. /* if channel is volume only, set current output */
  437. for (chan = CHAN1; chan <= CHAN4; chan++) {
  438. if (chan_mask & (1 << chan)) {
  439. #ifdef VOL_ONLY_SOUND
  440. #ifdef __PLUS
  441. if (g_Sound.nDigitized)
  442. #endif
  443. if ((AUDC[chan + chip_offs] & VOL_ONLY)) {
  444. #ifdef STEREO_SOUND
  445. #ifdef __PLUS
  446. if (stereo_enabled && chip & 0x01)
  447. #else
  448. if (chip & 0x01)
  449. #endif
  450. {
  451. sampbuf_lastval2 += AUDV[chan + chip_offs]
  452. - sampbuf_AUDV[chan + chip_offs];
  453. sampbuf_val2[sampbuf_ptr2] = sampbuf_lastval2;
  454. sampbuf_AUDV[chan + chip_offs] = AUDV[chan + chip_offs];
  455. sampbuf_cnt2[sampbuf_ptr2] =
  456. (cpu_clock - sampbuf_last2) * 128 * samp_freq / 178979;
  457. sampbuf_last2 = cpu_clock;
  458. sampbuf_ptr2++;
  459. if (sampbuf_ptr2 >= SAMPBUF_MAX)
  460. sampbuf_ptr2 = 0;
  461. if (sampbuf_ptr2 == sampbuf_rptr2) {
  462. sampbuf_rptr2++;
  463. if (sampbuf_rptr2 >= SAMPBUF_MAX)
  464. sampbuf_rptr2 = 0;
  465. }
  466. }
  467. else
  468. #endif /* STEREO_SOUND */
  469. {
  470. sampbuf_lastval += AUDV[chan + chip_offs]
  471. -sampbuf_AUDV[chan + chip_offs];
  472. sampbuf_val[sampbuf_ptr] = sampbuf_lastval;
  473. sampbuf_AUDV[chan + chip_offs] = AUDV[chan + chip_offs];
  474. sampbuf_cnt[sampbuf_ptr] =
  475. (cpu_clock - sampbuf_last) * 128 * samp_freq / 178979;
  476. sampbuf_last = cpu_clock;
  477. sampbuf_ptr++;
  478. if (sampbuf_ptr >= SAMPBUF_MAX)
  479. sampbuf_ptr = 0;
  480. if (sampbuf_ptr == sampbuf_rptr) {
  481. sampbuf_rptr++;
  482. if (sampbuf_rptr >= SAMPBUF_MAX)
  483. sampbuf_rptr = 0;
  484. }
  485. }
  486. }
  487. #endif /* VOL_ONLY_SOUND */
  488. /* I've disabled any frequencies that exceed the sampling
  489.    frequency.  There isn't much point in processing frequencies
  490.    that the hardware can't reproduce.  I've also disabled
  491.    processing if the volume is zero. */
  492. /* if the channel is volume only */
  493. /* or the channel is off (volume == 0) */
  494. /* or the channel freq is greater than the playback freq */
  495. if ( (AUDC[chan + chip_offs] & VOL_ONLY) ||
  496. ((AUDC[chan + chip_offs] & VOLUME_MASK) == 0)
  497. #if defined(__PLUS) && !defined(_WX_)
  498. || (!g_Sound.nBieniasFix && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8)))
  499. #else
  500. /* || (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))*/
  501. #endif
  502. ) {
  503. /* indicate the channel is 'on' */
  504. Outvol[chan + chip_offs] = 1;
  505. /* can only ignore channel if filtering off */
  506. if ((chan == CHAN3 && !(AUDCTL[chip] & CH1_FILTER)) ||
  507. (chan == CHAN4 && !(AUDCTL[chip] & CH2_FILTER)) ||
  508. (chan == CHAN1) ||
  509. (chan == CHAN2)
  510. #if defined(__PLUS) && !defined(_WX_)
  511. || (!g_Sound.nBieniasFix && (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8)))
  512. #else
  513. /* || (Div_n_max[chan + chip_offs] < (Samp_n_max >> 8))*/
  514. #endif
  515. ) {
  516. /* and set channel freq to max to reduce processing */
  517. Div_n_max[chan + chip_offs] = 0x7fffffffL;
  518. Div_n_cnt[chan + chip_offs] = 0x7fffffffL;
  519. }
  520. }
  521. }
  522. }
  523. /*    _enable(); */ /* RSF - removed for portability 31-MAR-97 */
  524. }
  525. /*****************************************************************************/
  526. /* Module:  Pokey_process()                                                  */
  527. /* Purpose: To fill the output buffer with the sound output based on the     */
  528. /*          pokey chip parameters.                                           */
  529. /*                                                                           */
  530. /* Author:  Ron Fries                                                        */
  531. /* Date:    January 1, 1997                                                  */
  532. /*                                                                           */
  533. /* Inputs:  *buffer - pointer to the buffer where the audio output will      */
  534. /*                    be placed                                              */
  535. /*          n - size of the playback buffer                                  */
  536. /*          num_pokeys - number of currently active pokeys to process        */
  537. /*                                                                           */
  538. /* Outputs: the buffer will be filled with n bytes of audio - no return val  */
  539. /*          Also the buffer will be written to disk if Sound recording is ON */
  540. /*                                                                           */
  541. /*****************************************************************************/
  542. static void Pokey_process_8(void *sndbuffer, unsigned sndn)
  543. {
  544. register uint8 *buffer = (uint8 *) sndbuffer;
  545. register uint16 n = sndn;
  546. register uint32 *div_n_ptr;
  547. register uint8 *samp_cnt_w_ptr;
  548. register uint32 event_min;
  549. register uint8 next_event;
  550. #ifdef CLIP_SOUND
  551. register int16 cur_val; /* then we have to count as 16-bit signed */
  552. #ifdef STEREO_SOUND
  553. register int16 cur_val2;
  554. #endif
  555. #else /* CLIP_SOUND */
  556. register uint8 cur_val; /* otherwise we'll simplify as 8-bit unsigned */
  557. #ifdef STEREO_SOUND
  558. register uint8 cur_val2;
  559. #endif
  560. #endif /* CLIP_SOUND */
  561. register uint8 *out_ptr;
  562. register uint8 audc;
  563. register uint8 toggle;
  564. register uint8 count;
  565. register uint8 *vol_ptr;
  566. /* set a pointer to the whole portion of the samp_n_cnt */
  567. #ifdef WORDS_BIGENDIAN
  568. samp_cnt_w_ptr = ((uint8 *) (&Samp_n_cnt[0]) + 3);
  569. #else
  570. samp_cnt_w_ptr = ((uint8 *) (&Samp_n_cnt[0]) + 1);
  571. #endif
  572. /* set a pointer for optimization */
  573. out_ptr = Outvol;
  574. vol_ptr = AUDV;
  575. /* The current output is pre-determined and then adjusted based on each */
  576. /* output change for increased performance (less over-all math). */
  577. /* add the output values of all 4 channels */
  578. cur_val = SAMP_MIN;
  579. #ifdef STEREO_SOUND
  580. #ifdef __PLUS
  581. if (stereo_enabled)
  582. #endif
  583. cur_val2 = SAMP_MIN;
  584. #endif /* STEREO_SOUND */
  585. count = Num_pokeys;
  586. do {
  587. if (*out_ptr++)
  588. cur_val += *vol_ptr;
  589. vol_ptr++;
  590. if (*out_ptr++)
  591. cur_val += *vol_ptr;
  592. vol_ptr++;
  593. if (*out_ptr++)
  594. cur_val += *vol_ptr;
  595. vol_ptr++;
  596. if (*out_ptr++)
  597. cur_val += *vol_ptr;
  598. vol_ptr++;
  599. #ifdef STEREO_SOUND
  600. #ifdef __PLUS
  601. if (stereo_enabled)
  602. #endif
  603. {
  604. count--;
  605. if (count) {
  606. if (*out_ptr++)
  607. cur_val2 += *vol_ptr;
  608. vol_ptr++;
  609. if (*out_ptr++)
  610. cur_val2 += *vol_ptr;
  611. vol_ptr++;
  612. if (*out_ptr++)
  613. cur_val2 += *vol_ptr;
  614. vol_ptr++;
  615. if (*out_ptr++)
  616. cur_val2 += *vol_ptr;
  617. vol_ptr++;
  618. }
  619. else
  620. break;
  621. }
  622. #endif /* STEREO_SOUND */
  623. count--;
  624. } while (count);
  625. /*
  626. #if defined (USE_DOSSOUND)
  627. cur_val += 32 * atari_speaker;
  628. #endif
  629. */
  630. /* loop until the buffer is filled */
  631. while (n) {
  632. /* Normally the routine would simply decrement the 'div by N' */
  633. /* counters and react when they reach zero.  Since we normally */
  634. /* won't be processing except once every 80 or so counts, */
  635. /* I've optimized by finding the smallest count and then */
  636. /* 'accelerated' time by adjusting all pointers by that amount. */
  637. /* find next smallest event (either sample or chan 1-4) */
  638. next_event = SAMPLE;
  639. event_min = READ_U32(samp_cnt_w_ptr);
  640. div_n_ptr = Div_n_cnt;
  641. count = 0;
  642. do {
  643. /* Though I could have used a loop here, this is faster */
  644. if (*div_n_ptr <= event_min) {
  645. event_min = *div_n_ptr;
  646. next_event = CHAN1 + (count << 2);
  647. }
  648. div_n_ptr++;
  649. if (*div_n_ptr <= event_min) {
  650. event_min = *div_n_ptr;
  651. next_event = CHAN2 + (count << 2);
  652. }
  653. div_n_ptr++;
  654. if (*div_n_ptr <= event_min) {
  655. event_min = *div_n_ptr;
  656. next_event = CHAN3 + (count << 2);
  657. }
  658. div_n_ptr++;
  659. if (*div_n_ptr <= event_min) {
  660. event_min = *div_n_ptr;
  661. next_event = CHAN4 + (count << 2);
  662. }
  663. div_n_ptr++;
  664. count++;
  665. } while (count < Num_pokeys);
  666. /* if the next event is a channel change */
  667. if (next_event != SAMPLE) {
  668. /* shift the polynomial counters */
  669. count = Num_pokeys;
  670. do {
  671. /* decrement all counters by the smallest count found */
  672. /* again, no loop for efficiency */
  673. div_n_ptr--;
  674. *div_n_ptr -= event_min;
  675. div_n_ptr--;
  676. *div_n_ptr -= event_min;
  677. div_n_ptr--;
  678. *div_n_ptr -= event_min;
  679. div_n_ptr--;
  680. *div_n_ptr -= event_min;
  681. count--;
  682. } while (count);
  683. WRITE_U32(samp_cnt_w_ptr, READ_U32(samp_cnt_w_ptr) - event_min);
  684. /* since the polynomials require a mod (%) function which is
  685.    division, I don't adjust the polynomials on the SAMPLE events,
  686.    only the CHAN events.  I have to keep track of the change,
  687.    though. */
  688. P4 = (P4 + event_min) % POLY4_SIZE;
  689. P5 = (P5 + event_min) % POLY5_SIZE;
  690. P9 = (P9 + event_min) % POLY9_SIZE;
  691. P17 = (P17 + event_min) % POLY17_SIZE;
  692. /* adjust channel counter */
  693. Div_n_cnt[next_event] += Div_n_max[next_event];
  694. /* get the current AUDC into a register (for optimization) */
  695. audc = AUDC[next_event];
  696. /* set a pointer to the current output (for opt...) */
  697. out_ptr = &Outvol[next_event];
  698. /* assume no changes to the output */
  699. toggle = FALSE;
  700. /* From here, a good understanding of the hardware is required */
  701. /* to understand what is happening.  I won't be able to provide */
  702. /* much description to explain it here. */
  703. /* if VOLUME only then nothing to process */
  704. if (!(audc & VOL_ONLY)) {
  705. /* if the output is pure or the output is poly5 and the poly5 bit */
  706. /* is set */
  707. if ((audc & NOTPOLY5) || bit5[P5]) {
  708. /* if the PURETONE bit is set */
  709. if (audc & PURETONE) {
  710. /* then simply toggle the output */
  711. toggle = TRUE;
  712. }
  713. /* otherwise if POLY4 is selected */
  714. else if (audc & POLY4) {
  715. /* then compare to the poly4 bit */
  716. toggle = (bit4[P4] == !(*out_ptr));
  717. }
  718. else {
  719. /* if 9-bit poly is selected on this chip */
  720. if (AUDCTL[next_event >> 2] & POLY9) {
  721. /* compare to the poly9 bit */
  722. toggle = ((poly9_lookup[P9] & 1) == !(*out_ptr));
  723. }
  724. else {
  725. /* otherwise compare to the poly17 bit */
  726. toggle = (((poly17_lookup[P17 >> 3] >> (P17 & 7)) & 1) == !(*out_ptr));
  727. }
  728. }
  729. }
  730. }
  731. /* check channel 1 filter (clocked by channel 3) */
  732. if ( AUDCTL[next_event >> 2] & CH1_FILTER) {
  733. /* if we're processing channel 3 */
  734. if ((next_event & 0x03) == CHAN3) {
  735. /* check output of channel 1 on same chip */
  736. if (Outvol[next_event & 0xfd]) {
  737. /* if on, turn it off */
  738. Outvol[next_event & 0xfd] = 0;
  739. #ifdef STEREO_SOUND
  740. #ifdef __PLUS
  741. if (stereo_enabled && (next_event & 0x04))
  742. #else
  743. if ((next_event & 0x04))
  744. #endif
  745. cur_val2 -= AUDV[next_event & 0xfd];
  746. else
  747. #endif /* STEREO_SOUND */
  748. cur_val -= AUDV[next_event & 0xfd];
  749. }
  750. }
  751. }
  752. /* check channel 2 filter (clocked by channel 4) */
  753. if ( AUDCTL[next_event >> 2] & CH2_FILTER) {
  754. /* if we're processing channel 4 */
  755. if ((next_event & 0x03) == CHAN4) {
  756. /* check output of channel 2 on same chip */
  757. if (Outvol[next_event & 0xfd]) {
  758. /* if on, turn it off */
  759. Outvol[next_event & 0xfd] = 0;
  760. #ifdef STEREO_SOUND
  761. #ifdef __PLUS
  762. if (stereo_enabled && (next_event & 0x04))
  763. #else
  764. if ((next_event & 0x04))
  765. #endif
  766. cur_val2 -= AUDV[next_event & 0xfd];
  767. else
  768. #endif /* STEREO_SOUND */
  769. cur_val -= AUDV[next_event & 0xfd];
  770. }
  771. }
  772. }
  773. /* if the current output bit has changed */
  774. if (toggle) {
  775. if (*out_ptr) {
  776. /* remove this channel from the signal */
  777. #ifdef STEREO_SOUND
  778. #ifdef __PLUS
  779. if (stereo_enabled && (next_event & 0x04))
  780. #else
  781. if ((next_event & 0x04))
  782. #endif
  783. cur_val2 -= AUDV[next_event];
  784. else
  785. #endif /* STEREO_SOUND */
  786. cur_val -= AUDV[next_event];
  787. /* and turn the output off */
  788. *out_ptr = 0;
  789. }
  790. else {
  791. /* turn the output on */
  792. *out_ptr = 1;
  793. /* and add it to the output signal */
  794. #ifdef STEREO_SOUND
  795. #ifdef __PLUS
  796. if (stereo_enabled && (next_event & 0x04))
  797. #else
  798. if ((next_event & 0x04))
  799. #endif
  800. cur_val2 += AUDV[next_event];
  801. else
  802. #endif /* STEREO_SOUND */
  803. cur_val += AUDV[next_event];
  804. }
  805. }
  806. }
  807. else { /* otherwise we're processing a sample */
  808. /* adjust the sample counter - note we're using the 24.8 integer
  809.    which includes an 8 bit fraction for accuracy */
  810. int iout;
  811. #ifdef STEREO_SOUND
  812. int iout2;
  813. #endif
  814. #ifdef INTERPOLATE_SOUND
  815. if (cur_val != last_val) {
  816. if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */
  817. iout = (cur_val * (*Samp_n_cnt) +
  818. last_val * (Samp_n_max - *Samp_n_cnt))
  819. / Samp_n_max;
  820. }
  821. else
  822. iout = cur_val;
  823. last_val = cur_val;
  824. }
  825. else
  826. iout = cur_val;
  827. #ifdef STEREO_SOUND
  828. #ifdef __PLUS
  829. if (stereo_enabled)
  830. #endif
  831. if (cur_val2 != last_val2) {
  832. if (*Samp_n_cnt < Samp_n_max) { /* need interpolation */
  833. iout2 = (cur_val2 * (*Samp_n_cnt) +
  834. last_val2 * (Samp_n_max - *Samp_n_cnt))
  835. / Samp_n_max;
  836. }
  837. else
  838. iout2 = cur_val2;
  839. last_val2 = cur_val2;
  840. }
  841. else
  842. iout2 = cur_val2;
  843. #endif  /* STEREO_SOUND */
  844. #else   /* INTERPOLATE_SOUND */
  845. iout = cur_val;
  846. #ifdef STEREO_SOUND
  847. #ifdef __PLUS
  848. if (stereo_enabled)
  849. #endif
  850. iout2 = cur_val2;
  851. #endif  /* STEREO_SOUND */
  852. #endif  /* INTERPOLATE_SOUND */
  853. #ifdef VOL_ONLY_SOUND
  854. #ifdef __PLUS
  855. if (g_Sound.nDigitized)
  856. #endif
  857. {
  858. if (sampbuf_rptr != sampbuf_ptr) {
  859. int l;
  860. if (sampbuf_cnt[sampbuf_rptr] > 0)
  861. sampbuf_cnt[sampbuf_rptr] -= 1280;
  862. while ((l = sampbuf_cnt[sampbuf_rptr]) <= 0) {
  863. sampout = sampbuf_val[sampbuf_rptr];
  864. sampbuf_rptr++;
  865. if (sampbuf_rptr >= SAMPBUF_MAX)
  866. sampbuf_rptr = 0;
  867. if (sampbuf_rptr != sampbuf_ptr)
  868. sampbuf_cnt[sampbuf_rptr] += l;
  869. else
  870. break;
  871. }
  872. }
  873. iout += sampout;
  874. #ifdef STEREO_SOUND
  875. #ifdef __PLUS
  876. if (stereo_enabled)
  877. #endif
  878. {
  879. if (sampbuf_rptr2 != sampbuf_ptr2) {
  880. int l;
  881. if (sampbuf_cnt2[sampbuf_rptr2] > 0)
  882. sampbuf_cnt2[sampbuf_rptr2] -= 1280;
  883. while ((l = sampbuf_cnt2[sampbuf_rptr2]) <= 0) {
  884. sampout2 = sampbuf_val2[sampbuf_rptr2];
  885. sampbuf_rptr2++;
  886. if (sampbuf_rptr2 >= SAMPBUF_MAX)
  887. sampbuf_rptr2 = 0;
  888. if (sampbuf_rptr2 != sampbuf_ptr2)
  889. sampbuf_cnt2[sampbuf_rptr2] += l;
  890. else
  891. break;
  892. }
  893. }
  894. iout2 += sampout2;
  895. }
  896. #endif  /* STEREO_SOUND */
  897. }
  898. #endif  /* VOL_ONLY_SOUND */
  899. #ifdef CLIP_SOUND
  900. if (iout > SAMP_MAX) { /* then check high limit */
  901. *buffer++ = (uint8) SAMP_MAX; /* and limit if greater */
  902. }
  903. else if (iout < SAMP_MIN) { /* else check low limit */
  904. *buffer++ = (uint8) SAMP_MIN; /* and limit if less */
  905. }
  906. else { /* otherwise use raw value */
  907. *buffer++ = (uint8) iout;
  908. }
  909. #ifdef STEREO_SOUND
  910. #ifdef __PLUS
  911. if (stereo_enabled) {
  912. if (iout2 > SAMP_MAX)
  913. *buffer++ = (uint8) SAMP_MAX;
  914. else if (iout2 < SAMP_MIN)
  915. *buffer++ = (uint8) SAMP_MIN;
  916. else
  917. *buffer++ = (uint8) iout2;
  918. }
  919. #else /* __PLUS */
  920. if (Num_pokeys > 1) {
  921. if ((stereo_enabled ? iout2 : iout) > SAMP_MAX) { /* then check high limit */
  922. *buffer++ = (uint8) SAMP_MAX; /* and limit if greater */
  923. }
  924. else if ((stereo_enabled ? iout2 : iout) < SAMP_MIN) { /* else check low limit */
  925. *buffer++ = (uint8) SAMP_MIN; /* and limit if less */
  926. }
  927. else { /* otherwise use raw value */
  928. *buffer++ = (uint8) (stereo_enabled ? iout2 : iout);
  929. }
  930. }
  931. #endif /* __PLUS */
  932. #endif /* STEREO_SOUND */
  933. #else /* CLIP_SOUND */
  934. *buffer++ = (uint8) iout; /* clipping not selected, use value */
  935. #ifdef STEREO_SOUND
  936. if (Num_pokeys > 1)
  937. #ifdef ASAP
  938. *buffer++ = (uint8) iout2;
  939. #else
  940. *buffer++ = (uint8) (stereo_enabled ? iout2 : iout);
  941. #endif
  942. #endif /* STEREO_SOUND */
  943. #endif /* CLIP_SOUND */
  944. #ifdef WORDS_BIGENDIAN
  945. *(Samp_n_cnt + 1) += Samp_n_max;
  946. #else
  947. *Samp_n_cnt += Samp_n_max;
  948. #endif
  949. /* and indicate one less byte in the buffer */
  950. n--;
  951. #ifdef STEREO_SOUND
  952. #ifdef __PLUS
  953. if (stereo_enabled)
  954. #endif
  955. if (Num_pokeys > 1)
  956. n--;
  957. #endif
  958. }
  959. }
  960. #ifdef VOL_ONLY_SOUND
  961. #ifdef __PLUS
  962. if (g_Sound.nDigitized)
  963. #endif
  964. {
  965. if (sampbuf_rptr == sampbuf_ptr)
  966. sampbuf_last = cpu_clock;
  967. #ifdef STEREO_SOUND
  968. #ifdef __PLUS
  969. if (stereo_enabled)
  970. #endif
  971. if (sampbuf_rptr2 == sampbuf_ptr2)
  972. sampbuf_last2 = cpu_clock;
  973. #endif /* STEREO_SOUND */
  974. }
  975. #endif  /* VOL_ONLY_SOUND */
  976. }
  977. #ifdef SERIO_SOUND
  978. static void Update_serio_sound_rf(int out, UBYTE data)
  979. {
  980. #ifdef VOL_ONLY_SOUND
  981. #ifdef __PLUS
  982. if (g_Sound.nDigitized) {
  983. #endif
  984. int bits, pv, future;
  985. if (!serio_sound_enabled) return;
  986. pv = 0;
  987. future = 0;
  988. bits = (data << 1) | 0x200;
  989. while (bits)
  990. {
  991. sampbuf_lastval -= pv;
  992. pv = (bits & 0x01) * AUDV[3]; /* FIXME!!! - set volume from AUDV */
  993. sampbuf_lastval += pv;
  994. sampbuf_val[sampbuf_ptr] = sampbuf_lastval;
  995. sampbuf_cnt[sampbuf_ptr] =
  996. (cpu_clock + future-sampbuf_last) * 128 * samp_freq / 178979;
  997. sampbuf_last = cpu_clock + future;
  998. sampbuf_ptr++;
  999. if (sampbuf_ptr >= SAMPBUF_MAX )
  1000. sampbuf_ptr = 0;
  1001. if (sampbuf_ptr == sampbuf_rptr ) {
  1002. sampbuf_rptr++;
  1003. if (sampbuf_rptr >= SAMPBUF_MAX)
  1004. sampbuf_rptr = 0;
  1005. }
  1006. /* 1789790/19200 = 93 */
  1007. future += 93; /* ~ 19200 bit/s - FIXME!!! set speed form AUDF [2] ??? */
  1008. bits >>= 1;
  1009. }
  1010. sampbuf_lastval -= pv;
  1011. #ifdef __PLUS
  1012. }
  1013. #endif
  1014. #endif  /* VOL_ONLY_SOUND */
  1015. }
  1016. #endif /* SERIO_SOUND */
  1017. static void Pokey_process_16(void *sndbuffer, unsigned sndn)
  1018. {
  1019. uint16 *buffer = (uint16 *) sndbuffer;
  1020. int i;
  1021. Pokey_process_8(buffer, sndn);
  1022. for (i = sndn - 1; i >= 0; i--) {
  1023. int smp = ((int) (((uint8 *) buffer)[i]) - 0x80) * 0x100;
  1024. if (smp > 32767)
  1025. smp = 32767;
  1026. else if (smp < -32768)
  1027. smp = -32768;
  1028. buffer[i] = smp;
  1029. }
  1030. }
  1031. #ifdef CONSOLE_SOUND
  1032. static void Update_consol_sound_rf(int set)
  1033. {
  1034. #ifdef VOL_ONLY_SOUND
  1035. static int prev_atari_speaker = 0;
  1036. static unsigned int prev_cpu_clock = 0;
  1037. int d;
  1038. #ifdef __PLUS
  1039. if (!g_Sound.nDigitized)
  1040. return;
  1041. #endif
  1042. if (!console_sound_enabled)
  1043. return;
  1044. if (!set && samp_consol_val == 0)
  1045. return;
  1046. sampbuf_lastval -= samp_consol_val;
  1047. if (prev_atari_speaker != atari_speaker) {
  1048. samp_consol_val = atari_speaker * 8 * 4; /* gain */
  1049. prev_cpu_clock = cpu_clock;
  1050. }
  1051. else if (!set) {
  1052. d = cpu_clock - prev_cpu_clock;
  1053. if (d < 114) {
  1054. sampbuf_lastval += samp_consol_val;
  1055. return;
  1056. }
  1057. while (d >= 114 /* CPUL */) {
  1058. samp_consol_val = samp_consol_val * 99 / 100;
  1059. d -= 114;
  1060. }
  1061. prev_cpu_clock = cpu_clock - d;
  1062. }
  1063. sampbuf_lastval += samp_consol_val;
  1064. prev_atari_speaker = atari_speaker;
  1065. sampbuf_val[sampbuf_ptr] = sampbuf_lastval;
  1066. sampbuf_cnt[sampbuf_ptr] =
  1067. (cpu_clock - sampbuf_last) * 128 * samp_freq / 178979;
  1068. sampbuf_last = cpu_clock;
  1069. sampbuf_ptr++;
  1070. if (sampbuf_ptr >= SAMPBUF_MAX)
  1071. sampbuf_ptr = 0;
  1072. if (sampbuf_ptr == sampbuf_rptr) {
  1073. sampbuf_rptr++;
  1074. if (sampbuf_rptr >= SAMPBUF_MAX)
  1075. sampbuf_rptr = 0;
  1076. }
  1077. #endif  /* VOL_ONLY_SOUND */
  1078. }
  1079. #endif /* CONSOLE_SOUND */
  1080. #ifdef VOL_ONLY_SOUND
  1081. static void Update_vol_only_sound_rf(void)
  1082. {
  1083. #ifdef CONSOLE_SOUND
  1084. Update_consol_sound(0); /* mmm */
  1085. #endif /* CONSOLE_SOUND */
  1086. }
  1087. #endif  /* VOL_ONLY_SOUND */