Annotation of generator/main/gensoundp-allegro.c, revision 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.