Annotation of generator/src/gensound-allegro.c, revision 1.1.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.