X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame_em%2Fsound.c;h=174d62384040e7964526e7ce874f92c0ef6cc405;hp=f03abf1e014abbb3c48d95f06b0117924c001396;hb=3ff2e8a0b5c27b99a9920bdf5ed82bc41bf40181;hpb=7bf1759dc1f54495a7e16b32f08697b00661c32e diff --git a/src/game_em/sound.c b/src/game_em/sound.c index f03abf1e..174d6238 100644 --- a/src/game_em/sound.c +++ b/src/game_em/sound.c @@ -4,514 +4,3 @@ */ #include "main_em.h" - - -#if defined(AUDIO_UNIX_NATIVE) - -#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) - -#ifdef PLATFORM_LINUX -#include -#include -#endif - -#ifdef PLATFORM_BSD -#include -#include -#endif - -static char audioname[] = "/dev/audio"; - -static const int sound_priority[SAMPLE_MAX] = -{ - SAMPLE_exit_open, - SAMPLE_exit_leave, - SAMPLE_die, - SAMPLE_time, - SAMPLE_boom, - SAMPLE_tick, - SAMPLE_collect, - SAMPLE_roll, - SAMPLE_push, - SAMPLE_dynamite, - SAMPLE_press, - SAMPLE_door, - SAMPLE_dirt, - SAMPLE_blank, - SAMPLE_android_clone, - SAMPLE_android_move, - SAMPLE_ball, - SAMPLE_grow, - SAMPLE_squash, - SAMPLE_wonderfall, - SAMPLE_crack, - SAMPLE_slurp, - SAMPLE_drip, - SAMPLE_wonder, - SAMPLE_wheel, - SAMPLE_stone, - SAMPLE_spring, - SAMPLE_diamond, - SAMPLE_nut, - SAMPLE_bug, - SAMPLE_tank, - SAMPLE_eater, - SAMPLE_eater_eat, - SAMPLE_alien, - SAMPLE_acid -}; - -int sound_thread(void) -{ - int audio_fd; /* file descriptor of /dev/audio or -1 if not open */ - int audio_format; - // int sample_rate; - int fragment_size; - unsigned char *audio_buffer; /* actual buffer pumped to /dev/audio */ - short *mix_buffer; - - char sound_play[SAMPLE_MAX]; /* if set, we should be playing these sounds */ - int sound_pos[SAMPLE_MAX]; /* position in the sound */ - int mix_play[MIXER_MAX]; /* which sounds we have chosen to mix (calculated each time) */ - int mix_count; - int i; - - loop: - - audio_fd = -1; - audio_format = AUDIO_ULAW; /* defaults for non-OSS /dev/audio */ - // sample_rate = 8000; - fragment_size = 256; - audio_buffer = 0; - mix_buffer = 0; - mix_count = 0; - - clear_mem(sound_play, sizeof(sound_play)); /* not playing any sounds */ - - for (;;) - { - for (;;) - { - - /* pick sounds to play, if any */ - if (sound_play[SAMPLE_exit_open] || - sound_play[SAMPLE_exit_leave] || - sound_play[SAMPLE_die]) - sound_play[SAMPLE_boom] = 0; /* no explosions if player goes home */ - - mix_count = 0; - for (i = 0; i < SAMPLE_MAX; i++) - { - if (sound_play[sound_priority[i]]) - { - mix_play[mix_count++] = sound_priority[i]; - - if (mix_count == MIXER_MAX) - break; /* cant mix too many sounds at once */ - } - } - - /* check for incoming messages */ - if (mix_count || audio_fd != -1) - { - /* dont block if we are playing sounds */ - fd_set rfds; - struct timeval tv; - FD_ZERO(&rfds); - FD_SET(sound_pipe[0], &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; /* (900000 * fragment_size / sample_rate) */ - i = select(sound_pipe[0] + 1, &rfds, 0, 0, &tv); /* dont block */ - - if (i == -1) - { - Error(ERR_WARN, "select() failed in sound thread"); - - goto fail; - } - - if (i == 0) - break; /* no messages */ - } - - /* get a message and start a sound */ - i = read(sound_pipe[0], &play, sizeof(play)); - - if (i == -1) - { - Error(ERR_WARN, "read() failed in sound thread"); - - goto fail; - } - - if (i == 0) - { - Error(ERR_WARN, "reading sound failed in sound thread"); - - goto fail; - } - - if (i != sizeof(play)) - { - Error(ERR_WARN, "bad message length in sound thread"); - - goto fail; - } - - for (i = 0; i < SAMPLE_MAX; i++) - { - if (play[i]) - { - sound_play[i] = 1; /* play this sound */ - sound_pos[i] = 0; /* start it from the start */ - } - } - } - - /* open the audio device if there are sounds to play */ - if (mix_count && audio_fd == -1) - { - audio_fd = open(audioname, O_WRONLY); - - if (audio_fd == -1) - goto reset; - -#ifdef OPEN_SOUND_SYSTEM - i = 0x00020008; - - if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &i) == -1) - { - Error(ERR_WARN, "unable to set fragment size in sound thread"); - - goto reset; - } - - if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i) == -1) - { - Error(ERR_WARN, "unable to query audio format in sound thread"); - - goto reset; - } - - /* prefer 8 bit unsigned and fall back on mu-law */ - audio_format = (i & AFMT_U8) ? AFMT_U8 : AFMT_MU_LAW; - - i = audio_format; - if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &i) == -1) - { - Error(ERR_WARN, "unable to set audio format in sound thread"); - - goto reset; - } - - if (i == AFMT_MU_LAW) - { - audio_format = AUDIO_ULAW; - } - else if (i == AFMT_U8) - { - audio_format = AUDIO_U8; - } - else - { - Error(ERR_WARN, "audio format required by device not supported"); - - goto reset; - } - - i = 1; - if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &i) == -1) - { - Error(ERR_WARN, "unable to set channels to mono in sound thread"); - - goto reset; - } - - if (i != 1) - { - Error(ERR_WARN, "channels required by device not supported"); - - goto reset; - } - - i = 8000; - if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &i) == -1) - { - Error(ERR_WARN, "unable to set sampling rate in sound thread"); - - goto reset; - } - - // sample_rate = i; - if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &i) == -1) - { - Error(ERR_WARN, "unable to get block size in sound thread"); - - goto reset; - } - - fragment_size = i; - -#else - if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) == -1) - { - Error(ERR_WARN, "unable to make audio non blocking in sound thread"); - - goto reset; - } - -#endif /* OPEN_SOUND_SYSTEM */ - - audio_buffer = malloc(fragment_size * sizeof(*audio_buffer)); - if (audio_buffer == 0) - { - Error(ERR_WARN, "unable to malloc audio buffer in sound thread"); - - goto fail; - } - - mix_buffer = malloc(fragment_size * sizeof(*mix_buffer)); - if (mix_buffer == 0) - { - Error(ERR_WARN, "unable to malloc mixing buffer in sound thread"); - - goto fail; - } - } - - /* close the audio device if no sounds are playing */ - if (mix_count == 0 && audio_fd != -1) - { - close(audio_fd); - free(audio_buffer); - free(mix_buffer); - audio_fd = -1; - audio_buffer = 0; - mix_buffer = 0; - } - - /* if we are playing sounds and the audio device is open, mix them */ - if (mix_count && audio_fd != -1) - { - /* prepare mix buffer */ - clear_mem(mix_buffer, fragment_size * sizeof(*mix_buffer)); - - for (i = 0; i < mix_count; i++) - { - register short *mix_ptr = mix_buffer; - register short *sound_ptr = - sound_data[mix_play[i]] + sound_pos[mix_play[i]]; - register int count = - sound_length[mix_play[i]] - sound_pos[mix_play[i]]; - - if (count > fragment_size) - count = fragment_size; - - while (count--) - *mix_ptr++ += *sound_ptr++; /* mix the sounds in */ - } - - switch(audio_format) - { - case AUDIO_ULAW: - for (i = 0; i < fragment_size; i++) - audio_buffer[i] = linear_to_ulaw[mix_buffer[i] + 32768]; - break; - - case AUDIO_U8: - for (i = 0; i < fragment_size; i++) - audio_buffer[i] = (mix_buffer[i] + 32768) >> 8; - break; - } - - /* advance sound pointers */ - for (i = 0; i < SAMPLE_MAX; i++) - { - if (sound_play[i]) - { - if (sound_pos[i] + fragment_size < sound_length[i]) - { - sound_pos[i] += fragment_size; - } - else - { - sound_play[i] = 0; - } - } - } - - /* send the data to the audio device */ - i = write(audio_fd, audio_buffer, fragment_size); - if (i == -1) - { - Error(ERR_WARN, "cannot write to audio device in sound thread"); - - goto reset; - } - - if (i != fragment_size) - { - Error(ERR_WARN, "bad write length to audio device in sound thread"); - - goto reset; - } - } - } /* for */ - - reset: - - if (audio_fd != -1) - close(audio_fd); - if (audio_buffer) - free(audio_buffer); - if (mix_buffer) - free(mix_buffer); - - goto loop; /* back to top */ - - fail: - if (audio_fd != -1) - close(audio_fd); - if (audio_buffer) - free(audio_buffer); - if (mix_buffer) - free(mix_buffer); - - return(0); -} - -int read_sample(char *name, short **data, int *length) -{ - int result; - FILE *file = 0; - short *dataptr = 0; - int datalength; - - int i, actual, ch; - unsigned char buffer[24]; - unsigned int temp; - - file = fopen(name, "rb"); - if (file == 0) - { - Error(ERR_WARN, "cannot open file '%s' in sound thread", name); - - result = 1; - goto fail; - } - - actual = fread(buffer, 1, 24, file); - if (actual == -1) - { - Error(ERR_WARN, "cannot read file '%s' in sound thread", name); - - result = 1; - goto fail; - } - - if (actual < 24) - { - Error(ERR_WARN, "premature eof of file '%s' in sound thread", name); - - result = 1; - goto fail; - } - - /* magic */ - temp = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; - if (temp != 0x2e736e64) - { - Error(ERR_WARN, "unrecognized format of file '%s' in sound thread", name); - - result = 1; - goto fail; - } - - /* header length */ - temp = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; - if (temp < 24) - { - Error(ERR_WARN, "bad header length of file '%s' in sound thread", name); - - result = 1; - goto fail; - } - - actual = temp; - for (i = 24; i < actual; i++) - { - /* skip the rest of the header */ - ch = fgetc(file); - if (ch == EOF) - break; - } - - /* data length */ - temp = buffer[8] << 24 | buffer[9] << 16 | buffer[10] << 8 | buffer[11]; - datalength = temp; - - /* encoding */ - temp = buffer[12] << 24 | buffer[13] << 16 | buffer[14] << 8 | buffer[15]; - if (temp != 1) - { - fprintf(stderr, "%s: \"%s\": %s (%d != 1)\n", progname, name, - "bad encoding type", temp); - result = 1; - goto fail; - } - - /* sample rate */ - temp = buffer[16] << 24 | buffer[17] << 16 | buffer[18] << 8 | buffer[19]; - if (temp != 8000) - { - fprintf(stderr, "%s: \"%s\": %s (%d != 8000)\n", progname, name, - "bad sample rate", temp); - result = 1; - goto fail; - } - - /* channels */ - temp = buffer[20] << 24 | buffer[21] << 16 | buffer[22] << 8 | buffer[23]; - if (temp != 1) - { - fprintf(stderr, "%s: \"%s\": %s (%d != 1)\n", progname, name, - "unsupported channels", temp); - result = 1; - goto fail; - } - - dataptr = malloc(datalength * sizeof(*dataptr)); - if (dataptr == 0) - { - Error(ERR_WARN, "unable to malloc buffer for file '%s' in sound thread", - name); - - result = 1; - goto fail; - } - - for (i = 0; i < datalength; i++) - { - ch = fgetc(file); - if (ch == EOF) break; - dataptr[i] = ulaw_to_linear[ch]; - } - - fclose(file); - file = 0; - - *data = dataptr; - *length = datalength; - result = 0; - - fail: - - if (file) - fclose(file); - - return(result); -} - -#endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */ - -#endif /* AUDIO_UNIX_NATIVE */