Annotation of generator/main/gensound.c, revision 1.1.1.2

1.1       root        1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
                      2: 
1.1.1.2 ! root        3: #include <stdlib.h>
1.1       root        4: 
                      5: #include "generator.h"
                      6: #include "gensound.h"
1.1.1.2 ! root        7: #include "gensoundp.h"
1.1       root        8: #include "vdp.h"
                      9: #include "ui.h"
1.1.1.2 ! root       10: #include "sn76496.h"
1.1       root       11: 
                     12: #ifdef JFM
                     13: #  include "jfm.h"
                     14: #else
                     15: #  include "support.h"
                     16: #  include "fm.h"
                     17: #endif
                     18: 
                     19: /*** variables externed ***/
                     20: 
1.1.1.2 ! root       21: int sound_debug = 0;            /* debug mode */
        !            22: int sound_feedback = 0;         /* -1, running out of sound
        !            23:                                    +0, lots of sound, do something */
        !            24: unsigned int sound_minfields = 5;       /* min fields to try to buffer */
        !            25: unsigned int sound_maxfields = 10;      /* max fields before blocking */
        !            26: unsigned int sound_speed;       /* sample rate */
        !            27: unsigned int sound_sampsperfield;       /* samples per field */
        !            28: unsigned int sound_threshold;   /* samples in buffer aiming for */
1.1       root       29: uint8 sound_regs1[256];
                     30: uint8 sound_regs2[256];
                     31: uint8 sound_address1 = 0;
                     32: uint8 sound_address2 = 0;
                     33: uint8 sound_keys[8];
                     34: 
1.1.1.2 ! root       35: /* pal is lowest framerate */
        !            36: uint16 sound_soundbuf[2][SOUND_MAXRATE / 50];
1.1       root       37: 
                     38: /*** forward references ***/
                     39: 
                     40: /*** file scoped variables ***/
                     41: 
                     42: static int sound_active = 0;
                     43: 
                     44: #ifdef JFM
1.1.1.2 ! root       45: static t_jfm_ctx *sound_ctx;
1.1       root       46: #endif
                     47: 
                     48: /*** sound_init - initialise this sub-unit ***/
                     49: 
                     50: int sound_init(void)
                     51: {
                     52:   int ret;
                     53: 
1.1.1.2 ! root       54:   /* The sound_minfields parameter specifies how many fields worth of sound we
        !            55:      should try and keep around (a display field is 1/50th or 1/60th of a
        !            56:      second) - generator works by trying to keep sound_minfields number of
        !            57:      fields worth of sound around, and drops plotting frames to keep up on slow
        !            58:      machines */
        !            59: 
        !            60:   sound_speed = SOUND_SAMPLERATE;
        !            61:   sound_sampsperfield = sound_speed / vdp_framerate;
        !            62:   sound_threshold = sound_sampsperfield * sound_minfields;
        !            63: 
1.1       root       64:   ret = sound_start();
                     65:   if (ret)
                     66:     return ret;
                     67: #ifdef JFM
1.1.1.2 ! root       68:   if ((sound_ctx = jfm_init(0, 2612, vdp_clock / 7, sound_speed,
        !            69:                             NULL, NULL)) == NULL) {
        !            70: #else
        !            71:   if (YM2612Init(1, vdp_clock / 7, sound_speed, NULL, NULL)) {
        !            72: #endif
        !            73:     LOG_VERBOSE(("YM2612 failed init"));
        !            74:     sound_stop();
        !            75:     return 1;
        !            76:   }
        !            77:   if (SN76496Init(0, vdp_clock / 15, 0, sound_speed)) {
        !            78:     LOG_VERBOSE(("SN76496 failed init"));
        !            79:     sound_stop();
        !            80: #ifdef JFM
        !            81:     jfm_final(sound_ctx);
1.1       root       82: #else
1.1.1.2 ! root       83:     YM2612Shutdown();
1.1       root       84: #endif
                     85:     return 1;
                     86:   }
                     87:   LOG_VERBOSE(("YM2612 Initialised @ sample rate %d", sound_speed));
                     88:   return 0;
                     89: }
                     90: 
                     91: /*** sound_final - finalise this sub-unit ***/
                     92: 
                     93: void sound_final(void)
                     94: {
                     95:   sound_stop();
                     96: #ifdef JFM
                     97:   jfm_final(sound_ctx);
                     98: #else
                     99:   YM2612Shutdown();
                    100: #endif
                    101: }
                    102: 
1.1.1.2 ! root      103: /*** sound_start - start sound ***/
1.1       root      104: 
                    105: int sound_start(void)
                    106: {
                    107:   if (sound_active)
                    108:     sound_stop();
1.1.1.2 ! root      109:   LOG_VERBOSE(("Starting sound..."));
        !           110:   if (soundp_start() == -1) {
        !           111:     LOG_VERBOSE(("Failed to start sound hardware"));
        !           112:     return -1;
1.1       root      113:   }
                    114:   sound_active = 1;
1.1.1.2 ! root      115:   LOG_VERBOSE(("Started sound."));
1.1       root      116:   return 0;
                    117: }
1.1.1.2 ! root      118: 
1.1       root      119: /*** sound_stop - stop sound ***/
                    120: 
                    121: void sound_stop(void)
                    122: {
                    123:   if (!sound_active)
                    124:     return;
                    125:   LOG_VERBOSE(("Stopping sound..."));
1.1.1.2 ! root      126:   soundp_stop();
1.1       root      127:   sound_active = 0;
                    128:   LOG_VERBOSE(("Stopped sound."));
                    129: }
1.1.1.2 ! root      130: 
1.1       root      131: /*** sound_reset - reset sound sub-unit ***/
                    132: 
                    133: int sound_reset(void)
                    134: {
                    135:   sound_final();
                    136:   return sound_init();
                    137: }
                    138: 
                    139: /*** sound_endfield - end frame and output sound ***/
                    140: 
                    141: void sound_endfield(void)
                    142: {
                    143:   unsigned int i;
1.1.1.2 ! root      144:   int pending;
        !           145: 
        !           146:   /* work out feedback from sound system */
        !           147: 
        !           148:   if ((pending = soundp_samplesbuffered()) == -1)
        !           149:     ui_err("Failed to read pending bytes in output sound buffer");
        !           150:   if ((unsigned int)pending < sound_threshold)
1.1       root      151:     sound_feedback = -1;
                    152:   else
                    153:     sound_feedback = 0;
1.1.1.2 ! root      154: 
1.1       root      155:   if (sound_debug) {
1.1.1.2 ! root      156:     LOG_VERBOSE(("End of field - sound system says %d bytes buffered",
        !           157:                  pending));
        !           158:     LOG_VERBOSE(("Threshold %d, therefore feedback = %d ", sound_threshold,
        !           159:                  sound_feedback));
1.1       root      160:   }
1.1.1.2 ! root      161:   soundp_output(sound_soundbuf[0], sound_soundbuf[1], sound_sampsperfield);
1.1       root      162: }
                    163: 
                    164: /*** sound_ym2612fetch - fetch byte from ym2612 chip ***/
                    165: 
                    166: uint8 sound_ym2612fetch(uint8 addr)
                    167: {
                    168: #ifdef JFM
                    169:   return jfm_read(sound_ctx, addr);
                    170: #else
                    171:   return YM2612Read(0, addr);
                    172: #endif
                    173: }
                    174: 
                    175: /*** sound_ym2612store - store a byte to the ym2612 chip ***/
                    176: 
                    177: void sound_ym2612store(uint8 addr, uint8 data)
                    178: {
                    179:   switch (addr) {
                    180:   case 0:
                    181:     sound_address1 = data;
                    182:     break;
                    183:   case 1:
                    184:     if (sound_address1 == 0x28 && (data & 3) != 3)
                    185:       sound_keys[data & 7] = data >> 4;
                    186:     if (sound_address1 == 0x2a) {
                    187:       sound_keys[7] = 0;
                    188:     }
                    189:     if (sound_address1 == 0x2b)
                    190:       sound_keys[7] = data & 0x80 ? 0xf : 0;
                    191:     sound_regs1[sound_address1] = data;
                    192:     break;
                    193:   case 2:
                    194:     sound_address2 = data;
                    195:     break;
                    196:   case 3:
                    197:     sound_regs2[sound_address2] = data;
                    198:     break;
                    199:   }
                    200: #ifdef JFM
                    201:   jfm_write(sound_ctx, addr, data);
                    202: #else
                    203:   YM2612Write(0, addr, data);
                    204: #endif
                    205: }
                    206: 
1.1.1.2 ! root      207: /*** sound_sn76496store - store a byte to the sn76496 chip ***/
        !           208: 
        !           209: void sound_sn76496store(uint8 data)
        !           210: {
        !           211:   SN76496Write(0, data);
        !           212: }
        !           213: 
        !           214: /*** sound_genreset - reset genesis sound ***/
        !           215: 
        !           216: void sound_genreset(void)
        !           217: {
        !           218: #ifdef JFM
        !           219:   jfm_reset(sound_ctx);
        !           220: #else
        !           221:   YM2612ResetChip(0);
        !           222: #endif
        !           223: }
        !           224: 
        !           225: /*** sound_process - process sound ***/
        !           226: 
        !           227: void sound_process(void)
        !           228: {
        !           229:   static sint16 *tbuf[2];
        !           230:   int s1 = (sound_sampsperfield * (vdp_line)) / vdp_totlines;
        !           231:   int s2 = (sound_sampsperfield * (vdp_line + 1)) / vdp_totlines;
        !           232:   /* pal is lowest framerate */
        !           233:   uint16 sn76496buf[SOUND_MAXRATE / 50];        /* far too much but who cares */
        !           234:   unsigned int samples = s2 - s1;
        !           235:   unsigned int i;
        !           236: 
        !           237:   tbuf[0] = sound_soundbuf[0] + s1;
        !           238:   tbuf[1] = sound_soundbuf[1] + s1;
        !           239: 
        !           240:   if (s2 > s1) {
        !           241: #ifdef JFM
        !           242:     jfm_update(sound_ctx, (void **)tbuf, samples1);
        !           243: #else
        !           244:     YM2612UpdateOne(0, (void **)tbuf, samples);
        !           245: #endif
        !           246:     SN76496Update(0, sn76496buf, samples);
        !           247: 
        !           248:     /* SN76496 outputs sound in range -0x4000 to 0x3fff
        !           249:        YM2612 ouputs sound in range -0x8000 to 0x7fff - therefore
        !           250:        we take 3/4 of the YM2612 and add half the SN76496 */
        !           251:     for (i = 0; i < samples; i++) {
        !           252:       sint16 snsample = sn76496buf[i] - 0x4000;
        !           253:       sint32 l = (tbuf[0][i] * 3) >> 2; /* left channel */
        !           254:       sint32 r = (tbuf[1][i] * 3) >> 2; /* right channel */
        !           255:       l += snsample >> 1;
        !           256:       r += snsample >> 1;
        !           257:       /* write with clipping
        !           258:          tbuf[0][i] = l > 0x7FFF ? 0x7fff : ((l < -0x7fff) ? -0x7fff : l);
        !           259:          tbuf[1][i] = r > 0x7FFF ? 0x7fff : ((r < -0x7fff) ? -0x7fff : r); */
        !           260:       tbuf[0][i] = l;
        !           261:       tbuf[1][i] = r;
        !           262:     }
        !           263:   }
        !           264: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.