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

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

unix.superglobalmegacorp.com

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