⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound_stuff.c

📁 这是一个相当棒的Linux下的台球游戏
💻 C
字号:
/* sound_stuff.c****    code for sound sample data**    Copyright (C) 2001  Florian Berger**    Email: harpin_floh@yahoo.de, florian.berger@jk.uni-linz.ac.at****    This program is free software; you can redistribute it and/or modify**    it under the terms of the GNU General Public License Version 2 as**    published by the Free Software Foundation;****    This program is distributed in the hope that it will be useful,**    but WITHOUT ANY WARRANTY; without even the implied warranty of**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the**    GNU General Public License for more details.****    You should have received a copy of the GNU General Public License**    along with this program; if not, write to the Free Software**    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***/#ifdef USE_SOUND#include "sound_stuff.h"#include "options.h"#ifdef USE_SDL#include "SDL.h"#include "SDL_audio.h"#endif#include <math.h>#include <stdio.h>#include <stdlib.h>#ifndef USE_SDL#include <sys/unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/soundcard.h>#include <fcntl.h>#endif#define NUM_SOUNDS 20#ifdef USE_SDLstatic struct sample {    Uint8 *data;    Uint32 dpos;    Uint32 dlen;    int    vol;} sounds[NUM_SOUNDS];#elsestatic struct sample {    int16_t *data;    int dpos;    int dlen;    int vol;} sounds[NUM_SOUNDS];#endif#ifndef USE_SDL#define SNDBUFF_SIZE 512#define MAXAMP_128  0x3FFF80#define MINAMP_128 -0x3FFF80int h_audio;long int  mixbuff[SNDBUFF_SIZE];int16_t   sndbuff[SNDBUFF_SIZE];#endif#ifdef USE_SDLstatic void mixaudio(void *userdata, Uint8 *stream, int len){    int i;    Uint32 amount;    for ( i=0; i<NUM_SOUNDS; ++i ) {        amount = (sounds[i].dlen-sounds[i].dpos);        if ( amount > len ) {            amount = len;        }/*        SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], amount, SDL_MIX_MAXVOLUME);*/        SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], amount, sounds[i].vol);        sounds[i].dpos += amount;    }}#elsevoid mixaudio(void){    int i,j;    int amount;    int sound_occured;    audio_buf_info info;    ioctl(h_audio, SNDCTL_DSP_GETOSPACE, &info);    sound_occured=1; /* for inital loop entry */    while ( info.bytes > SNDBUFF_SIZE*2  &&  sound_occured ){        sound_occured=0;        for ( i=0; i<NUM_SOUNDS; ++i ) {            if(sounds[i].dlen!=sounds[i].dpos){                if(!sound_occured){                    sound_occured=1;                    for(j=0;j<SNDBUFF_SIZE;j++) mixbuff[j]=0;                }                amount = (sounds[i].dlen-sounds[i].dpos);                if ( amount > SNDBUFF_SIZE ) {                    amount = SNDBUFF_SIZE;                }                for(j=0;j<amount;j++){                    mixbuff[j]+=sounds[i].data[sounds[i].dpos+j]*sounds[i].vol;                }                sounds[i].dpos += amount;            }        }        if(sound_occured){            for(j=0;j<SNDBUFF_SIZE;j++){                if        (mixbuff[j]>MAXAMP_128) {                    sndbuff[j] = MAXAMP_128/128;                } else if (mixbuff[j]<MINAMP_128) {                    sndbuff[j] = MINAMP_128/128;                } else {                    sndbuff[j] = mixbuff[j]/128;                }            }            write(h_audio,sndbuff,SNDBUFF_SIZE*2);        }        ioctl(h_audio, SNDCTL_DSP_GETOSPACE, &info);    }}#endifvoid PlayData(short int *data, int len, double ampl){    int index;//    SDL_AudioSpec wave;//    Uint32 dlen;//    SDL_AudioCVT cvt;    if(options_use_sound){        /* Look for an empty (or finished) sound slot */        for ( index=0; index<NUM_SOUNDS; ++index ) {            if ( sounds[index].dpos == sounds[index].dlen ) {                break;            }        }        if ( index == NUM_SOUNDS )            return;        /* Put the sound data in the slot (it starts playing immediately) */        if ( sounds[index].data ) {            //        free(sounds[index].data);        }#ifdef USE_SDL        SDL_LockAudio();#endif#ifdef USE_SDL        sounds[index].data = (Uint8 *)data;        sounds[index].dlen = len;#else        sounds[index].data = (int16_t *)data;        sounds[index].dlen = len/2;#endif        sounds[index].dpos = 0;        sounds[index].vol  = (int)(128.0*ampl);#ifdef USE_SDL        SDL_UnlockAudio();#endif    }}void PlaySound(TSound * snd, double ampl){    PlayData(snd->data, snd->len, ampl);}void PlaySound_offs(TSound * snd, double ampl, int offs_samps){    PlayData(&snd->data[offs_samps*2], snd->len-offs_samps*2*2, ampl);}int init_sound(void){#ifdef USE_SDL    SDL_AudioSpec fmt;    /* Set 16-bit stereo audio at 22Khz */    fmt.freq = 22050;    fmt.format = AUDIO_S16SYS;    fmt.channels = 2;    fmt.samples = 512;        /* A good value for games */    fmt.callback = mixaudio;    fmt.userdata = NULL;    /* Open the audio device and start playing sound! */    if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());        options_use_sound=0;    } else {        options_use_sound=1;    }    SDL_PauseAudio(0);    return 1;#else    audio_buf_info info;    int dummy;    h_audio = open("/dev/dsp", O_WRONLY, 0);    dummy = (6<<16) + 10;    ioctl(h_audio, SNDCTL_DSP_SETFRAGMENT, &dummy);    dummy = AFMT_S16_LE;    ioctl(h_audio, SNDCTL_DSP_SAMPLESIZE, &dummy);    dummy = 1;    ioctl(h_audio, SNDCTL_DSP_STEREO, &dummy);    dummy = 22050;    ioctl(h_audio, SNDCTL_DSP_SPEED, &dummy);    ioctl(h_audio, SNDCTL_DSP_GETOSPACE, &info);    DPRINTF("Info for output\n");    DPRINTF("   fragments  = %d\n",info.fragments );    DPRINTF("   fragstotal = %d\n",info.fragstotal);    DPRINTF("   fragsize   = %d\n",info.fragsize  );    DPRINTF("   bytes      = %d\n",info.bytes     );    return 1;#endif}int exit_sound(void){#ifdef USE_SDL    SDL_CloseAudio();    return 1;#else    close(h_audio);    return 1;#endif}double errsin(double x, double err){    double y;    y=(x-M_PI/4.0)/M_PI;    y-=floor(y);/*    if( y<0.5 ){        return (1.0-4.0*y);    }    return (-1.0+4.0*(y-0.5));*/    return(err*(double)rand()/(double)RAND_MAX+(1.0-err)*sin(x));}void create_expsinerr( double period_samps, double tau_samps, double err, short int ** data, int * len ){    int i;    *len=2*2*3*tau_samps;    *data=(short int *)malloc(*len);    for(i=0;i<(*len)/2/2;i++){        (*data)[i*2]=32000.0*errsin((double)i/period_samps*2.0*M_PI,err)*exp(-(double)i/tau_samps);        (*data)[i*2+1]=(*data)[i*2];    }    for(i=1;i<(*len)/2/2;i++){        (*data)[i*2]=0.5*(*data)[i*2]+0.5*(*data)[(i-1)*2];        (*data)[i*2+1]=(*data)[i*2];    }    for(i=30;i<(*len)/2/2;i++){        (*data)[i*2]=0.7*(*data)[i*2]+0.3*(*data)[(i-30)*2];        (*data)[i*2+1]=(*data)[i*2];    }}void create_delayed_expsinerr( double period_samps, double tau_samps, int delay_samps, double err, short int ** data, int * len ){    int i;    *len=2*2*3*tau_samps+2*2*delay_samps;    *data=(short int *)malloc(*len);    for(i=0;i<delay_samps;i++){        (*data)[i*2]=0;        (*data)[i*2+1]=0;    }    for(i=delay_samps+0;i<(*len)/2/2;i++){        (*data)[i*2]=32000.0*errsin((double)(i-delay_samps)/period_samps*2.0*M_PI,err)*exp(-(double)(i-delay_samps)/tau_samps);        (*data)[i*2+1]=(*data)[i*2];    }    for(i=delay_samps+1;i<(*len)/2/2;i++){        (*data)[i*2]=0.5*(*data)[i*2]+0.5*(*data)[(i-1)*2];        (*data)[i*2+1]=(*data)[i*2];    }    for(i=delay_samps+30;i<(*len)/2/2;i++){        (*data)[i*2]=0.7*(*data)[i*2]+0.3*(*data)[(i-30)*2];        (*data)[i*2+1]=(*data)[i*2];    }}void apply_bandpass( double period_samps, double width_samps, TSound snd ){    int len2, i, j;    double * filter, filterint;#define FILTERENTRY(filter,len,index) (((index)<(len)&&(index)>=0)?(filter)[(index)]:0.0)    len2 = 3*width_samps;    filter = malloc( len2*sizeof(double) );    /* construct filter */    filterint=0.0;    for(i=0;i<len2;i++){        filter[i]=            exp(-(double)(i-len2/2)*(double)(i-len2/2)/(double)width_samps/(double)width_samps) *            cos(2.0*M_PI*(double)(i-len2/2)/(double)period_samps);        filterint+=filter[i];    }    /* apply filter */    for(i=0;i<snd.len/2/2;i++){        double newdata1, newdata2;        newdata1=0.0;        newdata2=0.0;        for(j=0;j<len2;j++){            newdata1 += (double)TSoundENTRY(snd,(i+(j-len2/2))*2)   * FILTERENTRY(filter,len2,j);            newdata2 += (double)TSoundENTRY(snd,(i+(j-len2/2))*2+1) * FILTERENTRY(filter,len2,j);        }/*        newdata1 = (double)TSoundENTRY(snd,i*2)   * filterint;        newdata2 = (double)TSoundENTRY(snd,i*2+1) * filterint;*/        snd.data[i*2]   = newdata1/filterint;        snd.data[i*2+1] = newdata2/filterint;    }    free( filter );}void create_expsinerr_attack( double period_samps, double tau_samps, double err, double attack, short int ** data, int * len ){    int i;    *len=2*2*3*tau_samps;    *data=(short int *)malloc(*len);    for(i=0;i<(*len)/2/2;i++){        (*data)[i*2]=32000.0*errsin((double)i/period_samps*2.0*M_PI,err)*exp(-(double)i/tau_samps);        (*data)[i*2+1]=(*data)[i*2];    }    for(i=1;i<(*len)/2/2;i++){        (*data)[i*2]=0.5*(*data)[i*2]+0.5*(*data)[(i-1)*2];        (*data)[i*2+1]=(*data)[i*2];    }    for(i=30;i<(*len)/2/2;i++){        (*data)[i*2]=0.7*(*data)[i*2]+0.3*(*data)[(i-30)*2];        (*data)[i*2+1]=(*data)[i*2];    }    for(i=0;i<(*len)/2/2;i++){        (*data)[i*2]*=1.0-exp(-(double)i/(double)attack*(double)i/(double)attack);        (*data)[i*2+1]=(*data)[i*2];    }}void apply_attack( int offset, double attack, short int ** data, int * len ){    int i;    for(i=offset;i<(*len)/2/2;i++){        (*data)[i*2+0]*=1.0-exp(-(double)(i-offset)/(double)attack*(double)(i-offset)/(double)attack);        (*data)[i*2+1]*=1.0-exp(-(double)(i-offset)/(double)attack*(double)(i-offset)/(double)attack);    }}void create_expsin( double period_samps, double tau_samps, short int ** data, int * len ){    int i;    *len=2*2*3*tau_samps;    *data=(short int *)malloc(*len);    for(i=0;i<(*len)/2/2;i++){        (*data)[i*2]=32000.0*sin((double)i/period_samps*2.0*M_PI)*exp(-(double)i/tau_samps);        (*data)[i*2+1]=(*data)[i*2];    }}void create_expsin_otones( double period_samps, double tau_samps, double otonefact, short int ** data, int * len ){    int i,j;    double fact;    *len=2*2*3*tau_samps;    *data=(short int *)malloc(*len);    for(i=0;i<(*len)/2/2;i++){        fact=1.0;        (*data)[i*2]=0.0;        for(j=0;j<6;j++){            (*data)[i*2]+=fact*25000.0*sin((double)i/(period_samps/(double)j)*2.0*M_PI)*exp(-(double)i/tau_samps);            fact*=otonefact;        }        (*data)[i*2+1]=(*data)[i*2];    }}#endif  /* #ifdef USE_SOUND */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -