Annotation of generator/main/gensoundp-allegro.c, revision 1.1.1.2

1.1       root        1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
                      2: 
                      3: #include <sys/types.h>
                      4: #include <sys/stat.h>
                      5: #include <sys/ioctl.h>
                      6: #include <unistd.h>
                      7: #include <fcntl.h>
                      8: #include <errno.h>
                      9: #include <string.h>
                     10: #include <math.h>
1.1.1.2 ! root       11: #include <time.h>
1.1       root       12: 
                     13: #include "generator.h"
                     14: #include "gensound.h"
                     15: #include "gensoundp.h"
                     16: #include "vdp.h"
                     17: #include "ui.h"
                     18: 
                     19: #include <allegro.h>
                     20: 
                     21: /*** variables externed ***/
                     22: 
                     23: /*** forward references ***/
                     24: 
                     25: void sound_readyblock(void);
                     26: 
                     27: /*** file scoped variables ***/
                     28: 
                     29: static int soundp_format;
                     30: static int soundp_stereo;
                     31: static int soundp_frag;
                     32: static int soundp_fragsize;
                     33: static unsigned int soundp_speed;
                     34: 
                     35: static unsigned int soundp_block;
                     36: static SAMPLE *soundp_sample;
                     37: static int soundp_voice;
                     38: 
                     39: #ifdef JFM
                     40: static t_jfm_ctx *sound_ctx;
                     41: #endif
                     42: 
                     43: /*** soundp_start - start sound hardware ***/
                     44: 
                     45: int soundp_start(void)
                     46: {
                     47:   unsigned int i;
                     48:   uint16 *p;
                     49:   static int once = 0;
                     50: 
                     51:   if (!once) {
                     52:     once = 1;
                     53:     LOG_VERBOSE(("Initialising sound..."));
                     54:     if (detect_digi_driver(DIGI_AUTODETECT) < 1) {
                     55:       LOG_CRITICAL(("Allegro failed to detect hardware"));
                     56:       return 1;
                     57:     }
                     58:     if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL)) {
                     59:       LOG_CRITICAL(("Failed to initialise sound"));
                     60:       return 1;
                     61:     }
                     62:   }
                     63:   /* allocate block capable of holding sound_maxfields frames */
                     64:   if ((soundp_sample = create_sample(16, 1, sound_speed, sound_sampsperfield *
                     65:                                     sound_maxfields)) == NULL) {
                     66:     LOG_CRITICAL(("Failed to create sample"));
                     67:     return 1;
                     68:   }
                     69:   p = (uint16 *)soundp_sample->data;
                     70:   for (i = 0; i < sound_sampsperfield * sound_maxfields * 2; i--)
                     71:     p[i] = 0x8000;
                     72:   if ((soundp_voice = allocate_voice(soundp_sample)) == -1) {
                     73:     LOG_CRITICAL(("Failed to allocate voice"));
                     74:     destroy_sample(soundp_sample);
                     75:     return 1;
                     76:   }
                     77:   voice_set_playmode(soundp_voice, PLAYMODE_LOOP);
                     78:   voice_set_volume(soundp_voice, 256);
                     79:   voice_set_pan(soundp_voice, 128);
                     80:   voice_set_frequency(soundp_voice, sound_speed);
                     81:   voice_start(soundp_voice);
                     82:   soundp_block = sound_maxfields - 1;       /* next block to write to */
                     83:   LOG_VERBOSE(("YM2612 Initialised @ sample rate %d", sound_speed));
                     84:   sound_readyblock();
                     85:   return 0;
                     86: }
                     87: 
                     88: /*** soundp_stop - stop sound hardware ***/
                     89: 
                     90: void soundp_stop(void)
                     91: {
                     92:   voice_stop(soundp_voice);
                     93:   deallocate_voice(soundp_voice);
                     94:   destroy_sample(soundp_sample);
                     95: }
                     96: 
                     97: /*** soundp_samplesbuffered - how many samples are currently buffered? ***/
                     98: 
                     99: int soundp_samplesbuffered(void)
                    100: {
                    101:   int pos = voice_get_position(soundp_voice);
                    102:   unsigned int blockpos = pos / sound_sampsperfield;
                    103:   int pending;
                    104: 
                    105:   if (blockpos == soundp_block) /* erk, playing in the write block */
                    106:     pending = 0;
                    107:   else if (blockpos < soundp_block)
                    108:     pending = soundp_block - blockpos;
                    109:   else
                    110:     pending = soundp_block + sound_maxfields - blockpos;
                    111:   if (pending) /* quantisation means we've over estimated by one, so adjust */
                    112:     pending--;
                    113:   return (pending * sound_sampsperfield);
                    114: }
                    115: 
                    116: void soundp_output(uint16 *left, uint16 *right, unsigned int samples)
                    117: {
                    118:   int writepos = soundp_block * sound_sampsperfield;
                    119:   uint16 *buffer = soundp_sample->data + writepos * 2 * 2;  /* 16bit, stereo */
                    120:   unsigned int i;
                    121: 
                    122:   if (samples != sound_sampsperfield) {
                    123:     LOG_CRITICAL(("allegro sound can only be used in field blocks"));
                    124:     return;
                    125:   }
                    126:   /* write into new block */
                    127:   for (i = 0; i < samples; i++) {
                    128:     buffer[i * 2] = ((sint16)left[i]) + 0x8000;
                    129:     buffer[i * 2 + 1] = ((sint16)right[i]) + 0x8000;
                    130:   }
                    131:   soundp_block++;
                    132:   if (soundp_block >= sound_maxfields)
                    133:     soundp_block = 0;
                    134:   sound_readyblock();
                    135: }
                    136: 
                    137: void sound_readyblock(void)
                    138: {
                    139:   static int locked = 0;
                    140:   int writepos = soundp_block * sound_sampsperfield;
1.1.1.2 ! root      141:   time_t start = time(NULL);
1.1       root      142: 
                    143:   if (locked && digi_driver->unlock_voice)
                    144:     digi_driver->unlock_voice(soundp_voice);
                    145: 
                    146:   while ((voice_get_position(soundp_voice) /
                    147:           sound_sampsperfield) == soundp_block) {
1.1.1.2 ! root      148:     /* I used to usleep here, but it breaks on some platforms - then I
        !           149:        tried uclock() which failed too, so we're just going to busywait */
        !           150:     if (time(NULL) > start + 10) {
1.1       root      151:       LOG_CRITICAL(("Sound error - pos=%d %d=%d",
                    152:                     voice_get_position(soundp_voice),
                    153:                     sound_sampsperfield, soundp_block));
                    154:       exit(0);
                    155:     }
                    156:     /* cannot write to the next block until it's played! */
                    157:   }
                    158:   if (digi_driver->lock_voice) {
                    159:     digi_driver->lock_voice(soundp_voice, writepos,
                    160:                             writepos + sound_sampsperfield);
                    161:     locked = 1;
                    162:   }
                    163: }

unix.superglobalmegacorp.com

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