2 "$Id: cfsndserv.c 8649 2008-03-29 10:58:58Z ryo_saeba $";
52 #include <sys/types.h>
66 #ifdef HAVE_SYS_IOCTL_H
67 #include <sys/ioctl.h>
70 #ifdef HAVE_SYS_SELECT_H
71 #include <sys/select.h>
86 #if defined(ALSA_SOUND)
87 # include <sys/asoundlib.h>
88 # define AUDIODEV "/dev/dsp"
90 #elif defined(OSS_SOUND)
91 # include <sys/soundcard.h>
92 # define AUDIODEV "/dev/dsp"
93 #elif defined(SGI_SOUND)
95 # define AUDIODEV "/foo/bar"
96 #elif defined(SUN_SOUND)
97 # include <sys/audioio.h>
98 # define AUDIODEV "/dev/audio"
100 #error Not known sound system defined
103 #define CONFIG_FILE "/.crossfire/sndconfig"
104 #define MAX_SOUNDS 1024
112 char *c=(
char *)malloc(
sizeof(
char)*strlen(str)+1);
130 #define SOUND_DECREASE 0.1
168 static int readtype=0, lastnum=0;
170 char *cp,*volume,*symbolic,*cp1,filename[512];
172 if (line[0]==
'#' || line[0]==
'\n')
return;
174 if (!strcmp(line,
"Standard Sounds:\n")) {
179 if (!strcmp(line,
"Spell Sounds:\n")) {
186 fprintf(stderr,
"Got input without finding section header yet:\n%d:%s\n",
192 if (line[strlen(line)-1]==
'\n') line[strlen(line)-1]=
'\0';
194 len=strcspn(line,
" \t");
200 while (*cp!=
'\0' && (*cp==
' ' || *cp==
'\t'))
207 if (!(cp=strchr(cp1,
' ')) && !(cp=strchr(cp1,
'\t'))) {
212 while (*cp!=
'\0' && (*cp==
' ' || *cp==
'\t'))
219 if (*symbolic==
'"') {
221 for (cp=symbolic; *cp!=
'\0' && *cp!=
'"'; cp++) ;
227 if (!(cp=strchr(cp1,
' ')) && !(cp=strchr(cp1,
'\t')))
231 while (*cp!=
'\0' && (*cp==
' ' || *cp==
'\t'))
235 else newnum=lastnum+1;
239 fprintf(stderr,
"Invalid sound number %d, line %d, buf %s\n",
240 newnum, lineno, line);
248 strcpy(filename, line);
249 cp = filename + strlen(filename)-3;
250 if (!strcmp(cp,
".au"))
253 if (symbolic && !strcmp(symbolic,
"DEFAULT")) {
256 default_normal.
volume=atoi(volume);
257 }
else if (readtype==2) {
259 default_spell.
volume=atoi(volume);
266 normal_sounds[newnum].
volume = atoi(volume);
268 else normal_sounds[newnum].
symbolic=NULL;
269 }
else if (readtype==2) {
271 spell_sounds[newnum].
volume = atoi(volume);
273 else spell_sounds[newnum].
symbolic=NULL;
279 #if defined(ALSA_SOUND)
282 int card=0,device=0,
err;
283 snd_pcm_channel_params_t
params;
285 printf(
"cfsndserv compiled for ALSA sound system\n");
288 if ( (
err = snd_pcm_open( &
handle, card, device, SND_PCM_OPEN_PLAYBACK )) <0 ) {
289 fprintf( stderr,
"open failed: %s\n", snd_strerror(
err ) );
293 params.channel = SND_PCM_CHANNEL_PLAYBACK;
294 params.mode = SND_PCM_MODE_BLOCK;
297 params.format.format =
settings.
sign?SND_PCM_SFMT_S8:SND_PCM_SFMT_U8;
299 params.format.format =
settings.
sign?SND_PCM_SFMT_S16_LE:SND_PCM_SFMT_U16_LE;
304 params.buf.block.frags_max = 2;
305 params.buf.block.frags_min = 1;
307 if ( (
err = snd_pcm_channel_params(
handle, ¶ms )) < 0 ) {
308 fprintf( stderr,
"format setup failed: %s\nTrying defaults\n"
309 , snd_strerror(
err ) );
310 params.format.format = SND_PCM_SFMT_U8;
311 params.format.rate = 11025;
312 params.format.voices = 1;
313 if ( (
err = snd_pcm_channel_params(
handle, ¶ms )) < 0 ) {
314 fprintf( stderr,
"format setup failed: %s\n", snd_strerror(
err ) );
319 switch(params.format.format){
320 case SND_PCM_SFMT_S8:
324 case SND_PCM_SFMT_U8:
328 case SND_PCM_SFMT_S16_LE:
332 case SND_PCM_SFMT_U16_LE:
337 fprintf(stderr,
"Coulnd't set proper format\n");
342 stereo=(params.format.voices==1)?0:1;
345 soundfd=snd_pcm_file_descriptor(
handle,SND_PCM_CHANNEL_PLAYBACK);
346 snd_pcm_nonblock_mode(
handle, 1 );
356 #elif defined(OSS_SOUND)
360 const char *audiodev;
361 int value,format,tmp;
363 printf(
"cfsndserv compiled for OSS sound system\n");
367 if ( (audiodev=getenv(
"AUDIODEV")) == NULL ) {
370 soundfd = open(audiodev, (O_WRONLY|O_NONBLOCK), 0);
372 fprintf(stderr,
"Couldn't open %s: %s\n", audiodev, strerror(errno));
return(-1);
380 if ( ioctl(
soundfd, SNDCTL_DSP_SETFRAGMENT, &value) < 0 ) {
381 fprintf(stderr,
"Couldn't set audio fragment spec\n");
390 if ( (ioctl(
soundfd, SNDCTL_DSP_SETFMT,&value) < 0) ||
391 (value != format) ) {
392 fprintf(stderr,
"Couldn't set audio format\n");
421 fprintf(stderr,
"Couldn't set audio frequency\n");
431 printf(
"audio play - writing starting at %d, %d bytes",
437 printf(
"...wrote %d bytes\n", wrote);
444 #elif defined(SGI_SOUND)
446 ALconfig soundconfig;
453 printf(
"cfsndserv compiled for SGI sound system\n");
458 if ((soundconfig=ALnewconfig())==0)
460 fprintf(stderr,
"Could not allocate ALconfig structure.\n");
468 fprintf(stderr,
"Could not set number of channels.\n");
474 if (ALsetsampfmt(soundconfig,AL_SAMPFMT_TWOSCOMP)==-1)
476 fprintf(stderr,
"Could not set audio sample format.\n");
483 if (ALsetwidth(soundconfig,(
bit8=
settings.
bit8)?AL_SAMPLE_8:AL_SAMPLE_16)==-1)
485 fprintf(stderr,
"Could not set audio sample width.\n");
492 params[0]=AL_OUTPUT_RATE;
494 if (ALsetparams(AL_DEFAULT_DEVICE,params,2)==-1)
496 fprintf(stderr,
"Could not set output rate of default device.\n");
502 if ((soundport=ALopenport(
"cfsndserv port",
"w",soundconfig))==NULL)
504 fprintf(stderr,
"Could not open audio port.\n");
517 #elif defined(SUN_SOUND)
521 const char *audiodev;
522 int value,format,tmp;
523 audio_info_t audio_info;
524 audio_device_t audio_device;
526 printf(
"cfsndserv compiled for SUN sound system\n");
530 if ( (audiodev=getenv(
"AUDIODEV")) == NULL ) {
533 soundfd = open(audiodev, (O_WRONLY|O_NONBLOCK), 0);
535 fprintf(stderr,
"Couldn't open %s: %s\n", audiodev, strerror(errno));
return(-1);
538 if (ioctl(
soundfd, AUDIO_GETDEV, &audio_device) < 0) {
539 fprintf(stderr,
"Couldn't get audio device ioctl\n");
542 if ( ioctl(
soundfd, AUDIO_GETINFO, &audio_info) < 0 ) {
543 fprintf(stderr,
"Couldn't get audio information ioctl\n");
552 if (!strcmp(audio_device.name,
"SUNW,dbri")) {
556 audio_info.play.precision = 16;
557 audio_info.play.encoding=AUDIO_ENCODING_LINEAR;
558 audio_info.play.sample_rate=11025;
561 else if (!strcmp(audio_device.name,
"SUNW,CS4231")) {
565 audio_info.play.precision = 16;
566 audio_info.play.encoding=AUDIO_ENCODING_LINEAR;
567 audio_info.play.sample_rate=11025;
573 bit8=(audio_info.play.precision==8)?1:0;
576 fprintf(stderr,
"SUN_SOUND: bit8=%d, stereo=%d, freq=%d, sample_size=%d\n",
579 if ( ioctl(
soundfd, AUDIO_SETINFO, &audio_info) < 0 ) {
580 perror(
"Couldn't set audio information ioctl");
589 printf(
"audio play - writing starting at %d, %d bytes",
595 printf(
"...wrote %d bytes\n", wrote);
615 char path[256], buf[512];
618 fprintf( stderr,
"Settings: bits: %i, ",
settings.
bit8?8:16);
619 fprintf( stderr,
"%s, ",
settings.
sign?
"signed":
"unsigned");
638 fprintf( stderr,
"bits: %i, ",
bit8?8:16);
639 fprintf( stderr,
"%s, ",
sign?
"signed":
"unsigned");
640 fprintf( stderr,
"%s, ",
stereo?
"stereo":
"mono");
643 fprintf( stderr,
"0level: %i\n",
zerolevel);
649 normal_sounds[i].
size=-1;
650 spell_sounds[i].
size=-1;
655 sprintf(path,
"%s/.crossfire/sounds", getenv(
"HOME"));
657 if (!(fp=fopen(path,
"r"))) {
658 fprintf(stderr,
"Unable to open %s - will use built in defaults\n", path);
659 for (; i<
sizeof(
def_sounds)/
sizeof(
char*); i++) {
663 }
else while (fgets(buf, 511, fp)!=NULL) {
669 if (!normal_sounds[i].filename) {
673 if (!spell_sounds[i].filename) {
677 normal_sounds[i].
data=NULL;
678 spell_sounds[i].
data=NULL;
691 static void play_sound(
int soundnum,
int soundtype,
int x,
int y)
696 unsigned left_ratio,right_ratio;
711 fprintf(stderr,
"Invalid sound number: %d\n", soundnum);
715 fprintf(stderr,
"Sound device is not open\n");
722 si = &normal_sounds[soundnum];
725 si = &spell_sounds[soundnum];
728 fprintf(stderr,
"Unknown soundtype: %d\n", soundtype);
733 fprintf(stderr,
"Sound %d (type %d) is not defined\n", soundnum, soundtype);
745 fprintf(stderr,
"Loading file: %s\n",si->
filename);
751 si->
size=sbuf.st_size;
752 if (si->
size <=0 )
return;
754 fprintf(stderr,
"Sound %s too long (%i > %i)\n",si->
filename,si->
size,
758 si->
data=(
unsigned char *)malloc(si->
size);
769 fprintf(stderr,
"Playing sound %i (%s), volume %i, x,y=%d,%d\n",soundnum,si->
symbolic,si->
volume,x,y);
777 diff=(1.0-fabs((
double)x/dist));
781 printf(
"diff: %f\n",diff);
784 if (x<0) right_ratio*=diff;
785 else left_ratio*=diff;
789 fprintf(stderr,
"Ratio: %i, %i\n",left_ratio,right_ratio);
795 for(i=0;i<si->
size;i++){
796 int dat=si->
data[i]-0x80;
809 #ifdef WORDS_BIGENDIAN
843 fprintf(stderr,
"Added %d bytes, last buffer=%d, lastpos=%d\n",
864 i=sscanf((
char *)data,
"%x %x %x %x",&num,&type,&x,&y);
866 fprintf(stderr,
"Wrong input!\n");
870 fprintf(stderr,
"Playing sound %d (type %d), offset %d, %d\n",
882 if ( (home=getenv(
"HOME")) == NULL )
return -1;
883 path=(
char *)malloc(strlen(home)+strlen(
CONFIG_FILE)+1);
884 if (!path)
return -1;
889 fprintf(f,
"# Crossfire sound server settings\n");
890 fprintf(f,
"# Please note, that not everything will work\n\n");
908 if ( (home=getenv(
"HOME")) == NULL )
return 0;
910 path=(
char *)malloc(strlen(home)+strlen(
CONFIG_FILE)+1);
919 while(fgets(linebuf,1023,f)!=NULL) {
922 linebuf[strlen(linebuf)-1]=0;
924 if (strncmp(linebuf,
"stereo:",strlen(
"stereo:"))==0)
926 else if (strncmp(linebuf,
"bits:",strlen(
"bits:"))==0)
928 else if (strncmp(linebuf,
"signed:",strlen(
"signed:"))==0)
930 else if (strncmp(linebuf,
"buffers:",strlen(
"buffers:"))==0)
932 else if (strncmp(linebuf,
"buflen:",strlen(
"buflen:"))==0)
934 else if (strncmp(linebuf,
"frequency:",strlen(
"frequency:"))==0)
936 else if (strncmp(linebuf,
"simultaneously:",strlen(
"simultaneously:"))==0)
939 else if (strncmp(linebuf,
"device: ",strlen(
"device: "))==0)
947 int main(
int argc,
char *argv[])
966 #if defined(SGI_SOUND)
973 ALsetfillpoint(soundport,100000);
977 select(FD_SETSIZE,&inset,&outset,NULL,NULL);
979 if (FD_ISSET(
soundfd,&outset)){
1002 if (FD_ISSET(infd,&inset)){
1003 int err=read(infd,inbuf+inbuf_pos,1);
1004 if (err<1 && errno!=EINTR){
1005 if (err<0) perror(
"read");
1008 if (inbuf[inbuf_pos]==
'\n'){
1009 inbuf[inbuf_pos++]=0;
1010 if (!
SoundCmd((
unsigned char*)inbuf,inbuf_pos)) FD_SET(
soundfd,&outset);
1015 if (inbuf_pos>=1024){
1016 fprintf(stderr,
"Input buffer overflow!\n");
1021 FD_SET(infd,&inset);
int audio_play(int buffer, int off)
Sound_Info spell_sounds[MAX_SOUNDS]
snd_pcm_hw_params_t * params
char * strdup_local(char *str)
Sound_Info normal_sounds[MAX_SOUNDS]
static void parse_sound_line(char *line, int lineno)
int main(int argc, char *argv[])
int SoundCmd(unsigned char *data, int len)
struct sound_settings settings
struct Sound_Info Sound_Info
const char *const def_sounds[]
Sound_Info default_normal
static void play_sound(int soundnum, int soundtype, int x, int y)
static char * rcsid_cfsndserv_c