|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.