#include #include #include #include #include #include #include #include #include #include #include #include "v9t9_common.h" #include "timer.h" #include "sound.h" #include "9901.h" #include "mix_server.h" #define _L LOG_SOUND|LOG_INFO #define DEVICE "/dev/dsp" static int sound_fd; static int sound_dir = O_RDWR; static int soundhz = 44100; static int soundformat = AFMT_U8; static int soundblksize; //static int soundformat; #define SAMPLESIZE 512 //static s8 samplebuf[SAMPLESIZE]; #include "sound_pthread_mixer.h" static void sound_module_mix(void *buffer, int bytes) { write(sound_fd, buffer, bytes); } /****************************/ #define TRY(x,y) if (ioctl(sound_fd, x, y) < 0) \ { logger(_L|LOG_ERROR,"ossSound: ioctl failed (" #x "," #y "): %s\n", \ strerror(errno)); close(sound_fd); return 0; } static int setup_sound(void) { int soundstereo = 0; int soundformats; int soundfragment = 11 | (2 << 16); TRY(SNDCTL_DSP_SETFRAGMENT, &soundfragment); TRY(SNDCTL_DSP_RESET, 0); TRY(SNDCTL_DSP_GETBLKSIZE, &soundblksize); TRY(SNDCTL_DSP_SPEED, &soundhz); TRY(SNDCTL_DSP_STEREO, &soundstereo); TRY(SNDCTL_DSP_GETFMTS, &soundformats); if (!(soundformats & soundformat)) { logger(_L|LOG_USER, "OSS: desired sound quality not supported by hardware\n"); return 0; } TRY(SNDCTL_DSP_SETFMT, &soundformat); return 1; } /**************************************/ static void oss_update(vmsUpdateMask updated) { pthread_mixer_update(updated); } static void oss_flush(void) { pthread_mixer_flush(); } static void oss_play(vmsPlayMask kind, s8 * data, int len, int hz) { pthread_mixer_play(kind, data, len, hz); } /* read digital data (for cassette) */ static void oss_read(vmsReadMask kind, u8 * data, int len, int hz) { int x; read(sound_fd, data, len); if (soundformat == AFMT_S8) { for (x = 0; x < len; x++) data[x] ^= 0x80; } // for (x=0; x 0) { logger(_L|LOG_USER, "Detected Open Sound System...\n"); close(sound_fd); return vmOk; } else { logger(_L|LOG_ERROR | LOG_USER, "Could not open /dev/dsp: %s\n", strerror(errno)); return vmNotAvailable; } } static vmResult oss_init(void) { return vmOk; } static vmResult oss_term(void) { return vmOk; } static vmResult oss_enable(void) { if ((sound_fd = open(DEVICE, sound_dir = O_RDWR)) < 0 && (sound_fd = open(DEVICE, sound_dir = O_RDONLY)) < 0) { logger(_L|LOG_USER | LOG_ERROR, "OSS: cannot open sound (%s)\n", strerror(errno)); return vmNotAvailable; } if (!setup_sound()) return vmInternalError; pthread_mixer_init(soundhz, SAMPLESIZE, (soundformat == AFMT_S8 || soundformat == AFMT_S16_BE || soundformat == AFMT_S16_LE), (soundformat == AFMT_S8 || soundformat == AFMT_U8), (soundformat == AFMT_S16_BE || soundformat == AFMT_U16_BE)); return pthread_mixer_enable(); } static vmResult oss_disable(void) { vmResult res; if ((res = pthread_mixer_disable()) != vmOk) { logger(_L|0, "pthread_mixer_disable: %d\n", res); return res; } pthread_mixer_term(); close(sound_fd); return vmOk; } static vmResult oss_restart(void) { #warning set volume return pthread_mixer_restart(); } static vmResult oss_restop(void) { #warning reset volume return pthread_mixer_restop(); } static vmSoundModule ossSoundModule = { 3, oss_update, oss_flush, oss_play, oss_read }; vmModule ossSound = { 3, "Open Sound System", "sndOSS", vmTypeSound, 0, oss_detect, oss_init, oss_term, oss_enable, oss_disable, oss_restart, oss_restop, {(vmGenericModule *) & ossSoundModule} };