Annotation of generator/main/gensound-allegro.c, revision 1.1

1.1     ! root        1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
        !             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"
        !            19: #include "ui-console.h"
        !            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: 
        !            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 */
        !            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 */
        !            49: static int sound_active = 0;
        !            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;
        !            55: static unsigned int sound_threshold; /* bytes in buffer we're trying for */
        !            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: 
        !            69:   /* see sound_init in gensound.c for comments */
        !            70: 
        !            71:   if (!once) {
        !            72:     once = 1;
        !            73:     LOG_VERBOSE(("Initialising sound..."));
        !            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:   }
        !            84:   if (sound_active)
        !            85:     sound_final();
        !            86:   sound_threshold = sound_minfields;
        !            87:   sound_blocks = sound_threshold*2;
        !            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 *
        !            91:                                     sound_blocks)) == NULL) {
        !            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"));
        !           100:     destroy_sample(sound_sample);
        !           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,
        !           111:                             NULL, NULL)) == NULL) {
        !           112: #else
        !           113:   if (YM2612Init(1, vdp_clock/7, sound_speed, NULL, NULL)) {
        !           114: #endif
        !           115:     voice_stop(sound_voice);
        !           116:     deallocate_voice(sound_voice);
        !           117:     destroy_sample(sound_sample);
        !           118:     return 1;
        !           119:   }
        !           120:   LOG_VERBOSE(("YM2612 Initialised @ sample rate %d", sound_speed));
        !           121:   sound_active = 1;
        !           122:   sound_readyblock();
        !           123:   return 0;
        !           124: }
        !           125: 
        !           126: /*** sound_final - finalise this sub-unit ***/
        !           127: 
        !           128: void sound_final(void)
        !           129: {
        !           130:   if (!sound_active)
        !           131:     return;
        !           132:   LOG_VERBOSE(("Finalising sound..."));
        !           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);
        !           141:   sound_active = 0;
        !           142:   LOG_VERBOSE(("Finalised sound."));
        !           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) {
        !           208:       if ((sound_block - blockpos) < sound_threshold)
        !           209:         sound_feedback = -1;
        !           210:       else
        !           211:         sound_feedback = 0;
        !           212:     } else {
        !           213:       if ((sound_block - blockpos + sound_blocks) < sound_threshold)
        !           214:         sound_feedback = -1;
        !           215:       else
        !           216:         sound_feedback = 0;
        !           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) /
        !           235:          sound_sampsperfield) == sound_block) {
        !           236:     usleep(100);
        !           237:     a++;
        !           238:     if (a > 100000) {
        !           239:       LOG_CRITICAL(("Sound error - pos=%d %d=%d",
        !           240:                     voice_get_position(sound_voice),
        !           241:                     sound_sampsperfield, sound_block));
        !           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,
        !           248:                             writepos+sound_sampsperfield);
        !           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.