Annotation of generator/src/gensound-allegro.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
1.1       root        2: 
                      3: #include <string.h>
                      4: #include <stdio.h>
                      5: #include <sys/types.h>
                      6: #include <sys/stat.h>
                      7: #include <fcntl.h>
                      8: #include <errno.h>
                      9: #include <sys/ioctl.h>
                     10: #include <unistd.h>
                     11: #include <math.h>
                     12: 
                     13: #include <allegro.h>
                     14: 
                     15: #include "generator.h"
                     16: #include "gensound.h"
                     17: #include "vdp.h"
                     18: #include "ui.h"
1.1.1.2 ! root       19: #include "ui-console.h"
1.1       root       20: 
                     21: #ifdef JFM
                     22: #  include "jfm.h"
                     23: #else
                     24: #  include "support.h"
                     25: #  include "fm.h"
                     26: #endif
                     27: 
                     28: /*** variables externed ***/
                     29: 
1.1.1.2 ! root       30: int sound_feedback = 0;           /* -1, running out of sound
        !            31:                                      +0, lots of sound, do something */
        !            32: int sound_debug = 0;              /* 0 for no debug, 1 for debug */
        !            33: int sound_minfields = 5;          /* minimum fields to try to keep buffered */
        !            34: int sound_maxfields = 10;         /* max fields to buffer before blocking */
1.1       root       35: 
                     36: /* SN76489 snd_cpu; */
                     37: 
                     38: /*** forward references ***/
                     39: 
                     40: /* void snd_sndout(int chan, int freq, int vol); */
                     41: void sound_readyblock(void);
                     42: 
                     43: /*** file scoped variables ***/
                     44: 
                     45: #define SOUND_MAXRATE 44100
                     46: 
                     47: static unsigned int sound_sampsperfield = 0;
                     48: static uint16 soundbuf[2][SOUND_MAXRATE/50]; /* pal is lowest framerate */
1.1.1.2 ! root       49: static int sound_active = 0;
1.1       root       50: static unsigned int sound_speed;
                     51: static unsigned int sound_blocks;
                     52: static unsigned int sound_block;
                     53: static SAMPLE *sound_sample;
                     54: static int sound_voice;
1.1.1.2 ! root       55: static unsigned int sound_threshold; /* bytes in buffer we're trying for */
1.1       root       56: 
                     57: #ifdef JFM
                     58:   static t_jfm_ctx *sound_ctx;
                     59: #endif
                     60: 
                     61: /*** sound_init - initialise this sub-unit ***/
                     62: 
                     63: int sound_init(void)
                     64: {
                     65:   unsigned int i;
                     66:   uint16 *p;
                     67:   static int once = 0;
                     68: 
1.1.1.2 ! root       69:   /* see sound_init in gensound.c for comments */
        !            70: 
1.1       root       71:   if (!once) {
                     72:     once = 1;
1.1.1.2 ! root       73:     LOG_VERBOSE(("Initialising sound..."));
1.1       root       74:     sound_speed = SOUND_SAMPLERATE;
                     75:     if (detect_digi_driver(DIGI_AUTODETECT) < 1) {
                     76:       LOG_CRITICAL(("Allegro failed to detect hardware"));
                     77:       return 1;
                     78:     }
                     79:     if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL)) {
                     80:       LOG_CRITICAL(("Failed to initialise sound"));
                     81:       return 1;
                     82:     }
                     83:   }
1.1.1.2 ! root       84:   if (sound_active)
        !            85:     sound_final();
        !            86:   sound_threshold = sound_minfields;
        !            87:   sound_blocks = sound_threshold*2;
1.1       root       88:   sound_sampsperfield = SOUND_SAMPLERATE / vdp_framerate;
                     89:   /* allocate block capable of holding sound_blocks frames */
                     90:   if ((sound_sample = create_sample(16, 1, sound_speed, sound_sampsperfield *
1.1.1.2 ! root       91:                                     sound_blocks)) == NULL) {
1.1       root       92:     LOG_CRITICAL(("Failed to create sample"));
                     93:     return 1;
                     94:   }
                     95:   p = (uint16 *)sound_sample->data;
                     96:   for (i = 0; i < sound_sampsperfield*sound_blocks*2; i--)
                     97:     p[i] = 0x8000;
                     98:   if ((sound_voice = allocate_voice(sound_sample)) == -1) {
                     99:     LOG_CRITICAL(("Failed to allocate voice"));
1.1.1.2 ! root      100:     destroy_sample(sound_sample);
1.1       root      101:     return 1;
                    102:   }
                    103:   voice_set_playmode(sound_voice, PLAYMODE_LOOP);
                    104:   voice_set_volume(sound_voice, 256);
                    105:   voice_set_pan(sound_voice, 128);
                    106:   voice_set_frequency(sound_voice, sound_speed);
                    107:   voice_start(sound_voice);
                    108:   sound_block = sound_blocks-1; /* next block to write to */
                    109: #ifdef JFM
                    110:   if ((sound_ctx = jfm_init(0, 2612, vdp_clock/7, sound_speed,
1.1.1.2 ! root      111:                             NULL, NULL)) == NULL) {
1.1       root      112: #else
1.1.1.2 ! root      113:   if (YM2612Init(1, vdp_clock/7, sound_speed, NULL, NULL)) {
1.1       root      114: #endif
1.1.1.2 ! root      115:     voice_stop(sound_voice);
        !           116:     deallocate_voice(sound_voice);
        !           117:     destroy_sample(sound_sample);
1.1       root      118:     return 1;
1.1.1.2 ! root      119:   }
        !           120:   LOG_VERBOSE(("YM2612 Initialised @ sample rate %d", sound_speed));
        !           121:   sound_active = 1;
1.1       root      122:   sound_readyblock();
                    123:   return 0;
                    124: }
                    125: 
                    126: /*** sound_final - finalise this sub-unit ***/
                    127: 
                    128: void sound_final(void)
                    129: {
1.1.1.2 ! root      130:   if (!sound_active)
        !           131:     return;
        !           132:   LOG_VERBOSE(("Finalising sound..."));
1.1       root      133: #ifdef JFM
                    134:   jfm_final(sound_ctx);
                    135: #else
                    136:   YM2612Shutdown();
                    137: #endif
                    138:   voice_stop(sound_voice);
                    139:   deallocate_voice(sound_voice);
                    140:   destroy_sample(sound_sample);
1.1.1.2 ! root      141:   sound_active = 0;
        !           142:   LOG_VERBOSE(("Finalised sound."));
1.1       root      143: }
                    144: 
                    145: /*** sound_reset - reset sound sub-unit ***/
                    146: 
                    147: int sound_reset(void)
                    148: {
                    149:   sound_final();
                    150:   return sound_init();
                    151: }
                    152: 
                    153: /*** sound_genreset - reset genesis sound ***/
                    154: 
                    155: void sound_genreset(void)
                    156: {
                    157: #ifdef JFM
                    158:   jfm_reset(sound_ctx);
                    159: #else
                    160:   YM2612ResetChip(0);
                    161: #endif
                    162: }
                    163: 
                    164: /*** sound_process - process sound ***/
                    165: 
                    166: void sound_process(void)
                    167: {
                    168:   static uint16 *tbuf[2];
                    169:   int s1 = (sound_sampsperfield*(vdp_line))/vdp_totlines;
                    170:   int s2 = (sound_sampsperfield*(vdp_line+1))/vdp_totlines;
                    171: 
                    172:   tbuf[0] = soundbuf[0] + s1;
                    173:   tbuf[1] = soundbuf[1] + s1;
                    174: 
                    175:   /* printf("YM2612: %d to %d\n", s1, s2); */
                    176: 
                    177:   if (s2 > s1)
                    178: #ifdef JFM
                    179:     jfm_update(sound_ctx, (void **)tbuf, s2 - s1);
                    180: #else
                    181:     YM2612UpdateOne(0, (void **)tbuf, s2 -s1);
                    182: #endif
                    183: }
                    184: 
                    185: /*** sound_endfield - end frame and output sound ***/
                    186: 
                    187: void sound_endfield(void)
                    188: {
                    189:   static int oldpos = 0;
                    190:   int pos = voice_get_position(sound_voice);
                    191:   unsigned int blockpos = pos / sound_sampsperfield;
                    192:   int writepos = sound_block*sound_sampsperfield;
                    193:   uint16 *buffer = sound_sample->data + writepos*2*2; /* 16bit, stereo */
                    194:   unsigned int i;
                    195: 
                    196:   /* write into new block */
                    197:   for (i = 0; i < sound_sampsperfield; i++) {
                    198:     buffer[i*2] = ((sint16)soundbuf[0][i]) + 0x8000;
                    199:     buffer[i*2+1] = ((sint16)soundbuf[1][i]) + 0x8000;
                    200:   }
                    201:   if ((oldpos <= writepos && (pos < oldpos || pos > writepos)) ||
                    202:       (oldpos > writepos && (pos > writepos && pos < oldpos))) {
                    203:     /* under-run occured - reset to new sound block */
                    204:     voice_set_position(sound_voice, writepos);
                    205:     sound_feedback = -1;
                    206:   } else {
                    207:     if (blockpos < sound_block) {
1.1.1.2 ! root      208:       if ((sound_block - blockpos) < sound_threshold)
        !           209:         sound_feedback = -1;
1.1       root      210:       else
1.1.1.2 ! root      211:         sound_feedback = 0;
1.1       root      212:     } else {
1.1.1.2 ! root      213:       if ((sound_block - blockpos + sound_blocks) < sound_threshold)
        !           214:         sound_feedback = -1;
1.1       root      215:       else
1.1.1.2 ! root      216:         sound_feedback = 0;
1.1       root      217:     }
                    218:   }
                    219:   sound_block++;
                    220:   if (sound_block >= sound_blocks)
                    221:     sound_block = 0;
                    222:   sound_readyblock();
                    223:   oldpos = pos;
                    224: }
                    225: 
                    226: void sound_readyblock(void)
                    227: {
                    228:   static int locked = 0;
                    229:   int writepos = sound_block*sound_sampsperfield;
                    230:   unsigned int a = 0;
                    231:   if (locked && digi_driver->unlock_voice)
                    232:     digi_driver->unlock_voice(sound_voice);
                    233: 
                    234:   while((voice_get_position(sound_voice) /
1.1.1.2 ! root      235:          sound_sampsperfield) == sound_block) {
1.1       root      236:     usleep(100);
                    237:     a++;
                    238:     if (a > 100000) {
                    239:       LOG_CRITICAL(("Sound error - pos=%d %d=%d",
1.1.1.2 ! root      240:                     voice_get_position(sound_voice),
        !           241:                     sound_sampsperfield, sound_block));
1.1       root      242:       exit(0);
                    243:     }
                    244:     /* cannot write to the next block until it's played! */
                    245:   }
                    246:   if (digi_driver->lock_voice) {
                    247:     digi_driver->lock_voice(sound_voice, writepos,
1.1.1.2 ! root      248:                             writepos+sound_sampsperfield);
1.1       root      249:     locked = 1;
                    250:   }
                    251: }
                    252: 
                    253: #ifdef JFM
                    254: 
                    255: /*** sound_ym2612fetch - fetch byte from ym2612 chip ***/
                    256: 
                    257: uint8 sound_ym2612fetch(uint8 addr)
                    258: {
                    259:   return jfm_read(sound_ctx, addr);
                    260: }
                    261: 
                    262: /*** sound_ym2612store - store a byte to the ym2612 chip ***/
                    263: 
                    264: void sound_ym2612store(uint8 addr, uint8 data)
                    265: {
                    266:   jfm_write(sound_ctx, addr, data);
                    267: }
                    268: 
                    269: #endif

unix.superglobalmegacorp.com

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