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

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

unix.superglobalmegacorp.com

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