puts("[audio] initializing audio ...");
- if((audio->fd=open(audio->device,O_RDONLY))==-1) {
+ if((audio->dsp_fd=open(audio->dsp_dev,O_RDWR))==-1) {
perror("[audio] open call");
return A_ERROR;
}
- if(ioctl(audio->fd,SNDCTL_DSP_GETCAPS,&(audio->cap))==-1) {
+ if(ioctl(audio->dsp_fd,SNDCTL_DSP_GETCAPS,&(audio->dsp_cap))==-1) {
perror("[audio] ioctl call");
return A_ERROR;
}
-
+ if(!(audio->dsp_cap&DSP_CAP_DUPLEX)) {
+ puts("[audio] no duplex support");
+ return A_ERROR;
+ }
+
+ return A_SUCCESS;
+}
+
+int audio_setup(t_audio *audio) {
+
+ int tmp;
+
+ puts("[audio] setting up sound device & allocating record/playback buffer");
+
+ tmp=audio->fmt;
+ if(ioctl(audio->dsp_fd,SNDCTL_DSP_SETFMT,&tmp)==-1) {
+ perror("[audio] ioctl call (SNDCTL_DSP_SETFMT)");
+ return A_ERROR;
+ }
+ if(tmp!=audio->fmt) {
+ puts("[audio] FMT not supported");
+ return A_ERROR;
+ }
+
+ tmp=audio->speed;
+ if(ioctl(audio->dsp_fd,SNDCTL_DSP_SPEED,&tmp)==-1) {
+ perror("[audio] ioctl call (SNDCTL_DSP_SPEED)");
+ return A_ERROR;
+ }
+ if(tmp!=audio->speed) {
+ puts("[audio] SPEED not supported");
+ return A_ERROR;
+ }
+
+ if(ioctl(audio->dsp_fd,SNDCTL_DSP_GETBLKSIZE,&(audio->blksize))==-1) {
+ perror("[audio] ioctl call (SNDCTL_DSP_GETBLKSIZE)");
+ return A_ERROR;
+ }
+
+ if((audio->play_data=(unsigned char *)malloc(audio->blksize))==NULL) {
+ perror("[audio] malloc call");
+ return A_ERROR;
+ }
+ if((audio->rec_data=(unsigned char *)malloc(audio->blksize))==NULL) {
+ perror("[audio] malloc call");
+ return A_ERROR;
+ }
+
+ return A_SUCCESS;
+}
+
+int audio_shutdown(t_audio *audio) {
+
+ puts("[audio] shutdown");
+
+ free(audio->play_data);
+ free(audio->rec_data);
+
+ if(close(audio->dsp_fd)==-1) {
+ perror("[audio] close call");
+ return A_ERROR;
+ }
+
+ return A_SUCCESS;
+}
+
+int audio_play(t_audio *audio,int len) {
+
+ int count,left;
+
+ count=0;
+ left=len;
+
+ while(left) {
+ if((count=write(audio->dsp_fd,audio->play_data+len-left,left))==-1) {
+ perror("[audio] write call");
+ return A_ERROR;
+ }
+ left-=count;
+ }
+
+ return A_SUCCESS;
+}
+
+int audio_record(t_audio *audio,int len) {
+
+ int count,left;
+
+ count=0;
+ left=len;
+
+ while(left) {
+ if((count=read(audio->dsp_fd,audio->rec_data+len-left,left))==-1) {
+ perror("[audio] read call");
+ return A_ERROR;
+ }
+ left-=count;
+ }
+
+ return A_SUCCESS;
+}
#define AUDIO_H
/* includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <sys/soundcard.h>
/* defines */
#define MAX_CHAR_DEVICE 32
#define SOUND_DEVICE "/dev/dsp"
+#define A_SUCCESS 1
+#define A_ERROR -1
+
+#define BIT_8 AFMT_U8
+#define BIT_16 AFMT_S16_LE
+#define MONO 1
+#define STEREO 2
+
/* audio specific variables */
typedef struct s_audio {
- int fd;
- char device[MAX_CHAR_DEVICE];
- int cap;
+ int dsp_fd;
+ int mixer_fd;
+ char dsp_dev[MAX_CHAR_DEVICE];
+ char mixer_dev[MAX_CHAR_DEVICE];
+ int dsp_cap;
+ int fmt;
+ int channels;
+ int speed;
+ int blksize;
+ int mixer_cap;
+ unsigned char volume;
+ unsigned char *play_data;
+ unsigned char *rec_data;
} t_audio;
+/* function prototypes */
+int audio_init(t_audio *audio);
+int audio_setup(t_audio *audio);
+int audio_shutdown(t_audio *audio);
+int audio_play(t_audio *audio,int len);
+int audio_record(t_audio *audio,int len);
+
#endif
*
*/
-// #define USE_NCURSES
-/* dont care about ncurses .. go for gtk(2)! */
-#define USE_GTK
+// #define USE_GTK
#include "ivac.h"
puts("-h \t\t show this help");
puts("-n <name> \t specify your name");
puts("-p <port> \t specify port to listen for incoming connections");
+ puts("-d <device> \t specify audio device");
puts("");
return SUCCESS;
/* default values */
strcpy(ivac.username,"ivac");
ivac.net.l_port=IVAC_LISTEN_PORT;
+ strcpy(ivac.audio.dsp_dev,SOUND_DEVICE);
/* parse argv and change default values */
for(i=1;i<argc;i++) {
case 'p':
ivac.net.l_port=atoi(argv[++i]);
break;
+ case 'd':
+ strncpy(ivac.audio.dsp_dev,argv[++i],MAX_CHAR_DEVICE);
+ break;
default:
usage();
return ERROR;
event_math(ivac.net.l_fd,&(ivac.event),READ,ADD);
event_math(0,&(ivac.event),READ,ADD);
-#ifdef USE_NCURSES
/* display init */
display_init(&(ivac.display));
-#endif
+
+ /* use hardcoded audio settings by now */
+ ivac.audio.fmt=BIT_8;
+ ivac.audio.channels=MONO;
+ ivac.audio.speed=8000;
+ /* audio init */
+ audio_init(&(ivac.audio));
/* display */
ivac_display(&(ivac.display));
network_shutdown(&(ivac->net));
input_shutdown(&(ivac->input));
event_stop(&(ivac->event));
-#ifdef USE_NCURSES
+ audio_shutdown(&(ivac->audio));
display_shutdown(&(ivac->display));
-#endif
return SUCCESS;
}
int ivac_display_head(t_display *display) {
-#ifdef USE_NCURSES
- int x,y;
-
- move(0,0);
- for(x=0;x<display->max_x;x++) addch('#');
- mvaddstr(1,0,"##");
- mvaddstr(1,(display->max_x-4)/2-4,"- ivac -");
- mvaddstr(1,(display->max_x-2),"##");
- move(2,0);
- for(x=0;x<display->max_x;x++) addch('#');
- refresh();
-#else
puts("#########################################################");
puts("##### ivac - - Copyright (C) 2004 Frank Zirkelbach #####");
puts("#########################################################");
-#endif
return SUCCESS;
}
int ivac_display_box(t_display *display) {
-#ifdef USE_NCURSES
- int x,y;
-
- for(y=IVAC_PROMPT_LEN;y<display->max_y-IVAC_PROMPT_LEN;y++) {
- mvaddch(y,0,'#');
- mvaddch(y,display->max_x-1,'#');
- }
-#endif
-
return SUCCESS;
}
if(ivac->challenger[channel].name[0]==0)
strcpy(ivac->challenger[channel].name,"<empty>");
-#ifdef USE_NCURSES
-#else
- for(channel=0;channel<MAX_CONNECTIONS;channel++) {
- if(ivac->net.connection[channel].status&C_INFO_A)
- printf("channel %02d: ip:%s port:%d status: %02x - name: %s\n",channel,
- ivac->net.connection[channel].ip,
- ivac->net.connection[channel].port,
- ivac->net.connection[channel].status,
- ivac->challenger[channel].name);
- }
-#endif
-
return SUCCESS;
}
int ivac_display_console(t_display *display) {
-#ifdef USE_NCURSES
- int x,y;
-
- move(display->max_y-IVAC_CONSOLE_LEN-IVAC_PROMPT_LEN-1,0);
- for(x=0;x<display->max_x;x++) addch('#');
-#endif
-
return SUCCESS;
}
int ivac_display_console_content(t_ivac *ivac) {
-#ifdef USE_NCURSES
- int x,y;
- int len;
-
- for(y=0;y<IVAC_CONSOLE_LEN;y++) {
- len=strlen(ivac->console[y]);
- move(ivac->display.max_y-IVAC_CONSOLE_LEN-IVAC_PROMPT_LEN+y,2);
- for(x=0;x<len;x++)
- addch(((ivac->console[y][x]>' ')||(ivac->console[y][x]<='~'))
- ?ivac->console[y][x]:' ');
- for(x=len;x<IVAC_CONSOLE_STRING_LEN-4;x++) addch(' ');
- }
- refresh();
-#else
int i;
for(i=0;i<IVAC_CONSOLE_LEN;i++)
printf("[ivac] console line %d: %s\n",i,ivac->console[i]);
-#endif
return SUCCESS;
}
int ivac_display_prompt(t_display *display) {
-#ifdef USE_NCURSES
- int x,y;
-
- move(display->max_y-3,0);
- for(x=0;x<display->max_x;x++) addch('#');
- mvaddstr(display->max_y-2,0,"## command: ");
- mvaddstr(display->max_y-2,display->max_x-2,"##");
- move(display->max_y-1,0);
- for(x=0;x<display->max_x;x++) addch('#');
- refresh();
-#endif
-
return SUCCESS;
}
int ivac_display_prompt_content(t_ivac *ivac) {
-#ifdef USE_NCURSES
- int x,y;
-
- /* delete old command */
- if(ivac->input.c_count==0) {
- move(ivac->display.max_y-2,12);
- for(x=12;x<ivac->display.max_x-1;x++) addch(' ');
- }
-
- for(x=0;x<ivac->input.c_count;x++)
- mvaddch(ivac->display.max_y-2,x+12,ivac->input.content[x]);
- refresh();
-#else
printf("%c",ivac->input.content[ivac->input.c_count-1]);
fflush(NULL);
-#endif
return SUCCESS;
}