checked in buggy bullshit .. 2lame
[sound-tools/hdrec.git] / hdrec.c
1 /*
2  * hdrec -- some sort of multi tracker (not right now, but in the future :p)
3  *
4  * author: hackbard@hackdaworld.dyndns.org
5  *
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/ioctl.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/select.h>
15 #include <sys/time.h>
16 #include <sys/soundcard.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <errno.h>
20
21 #include "oss_api.h"
22 #include "hdrec.h"
23
24 int usage(void) {
25         printf("usage:\n\n");
26         printf("-h \t\t print this help\n");
27         printf("-i \t\t use/print file info\n");
28         printf("-d <device> \t sound device (eg: /dev/dsp)\n");
29         printf("-r <file> \t record to <file>\n");
30         printf("-p <file> \t play from <file>\n");
31         printf("-s \t\t stereo\n");
32         printf("-m \t\t mono\n");
33         printf("-f <format> \t 1=8bit - 2=16bit (le)\n");
34         printf("-F <hz> \t frequency\n");
35         printf("-c <src> <dst> \t converts raw to wav (specify f/m,s/F)\n");
36         
37         return 1;
38 }
39
40 int main(int argc,char **argv) {
41         int sfile_fd;
42         int pfile_fd;
43         int audio_fd;
44         char device[MAX_C_DEVICE];
45         int i,j,k;
46         int rw;
47         unsigned char mode=0;
48         int o_mode=0;
49         char record_file[MAX_C_FILE];
50         char play_file[MAX_C_FILE];
51         dsp_set set;
52         unsigned char *buf;
53         unsigned char *buf2=NULL;
54         unsigned char print_info=0;
55         unsigned char info[8];
56         int info_int;
57         int tmp;
58         fd_set read_fds,write_fds;
59         struct timeval fds_tv;
60         char c;
61
62         /* defaults */
63         strcpy(device,"");
64         set.format=AFMT_S16_LE;
65         set.freq=44100;
66         set.channel=STEREO;
67
68         /* read argv */
69         for(i=1;i<argc;i++) {
70                 if(argv[i][0]=='-') {
71                         switch(argv[i][1]) {
72                                 case 'h':
73                                         usage();
74                                         return 1;
75                                 case 'i':
76                                         print_info=1;
77                                         break;
78                                 case 'r':
79                                         mode|=RECORD;
80                                         strcpy(record_file,argv[++i]);
81                                         break;
82                                 case 'p':
83                                         mode|=PLAY;
84                                         strcpy(play_file,argv[++i]);
85                                         break;
86                                 case 's':
87                                         set.channel=STEREO;
88                                         break;
89                                 case 'm':
90                                         set.channel=MONO;
91                                         break;
92                                 case 'f':
93                                         i++;
94                                         if(atoi(argv[i])==1) set.format=AFMT_U8;
95                                         if(atoi(argv[i])==2) set.format=AFMT_S16_LE;
96                                         break;
97                                 case 'F':
98                                         set.freq=atoi(argv[++i]);
99                                         break;
100                                 case 'd':
101                                         strncpy(device,argv[++i],MAX_C_DEVICE-1);
102                                         break;
103                                 case 'c':
104                                         mode=CONVERT;
105                                         strcpy(play_file,argv[++i]);
106                                         strcpy(record_file,argv[++i]);
107                                         break;
108                                 default:
109                                         usage();
110                                         return -1;
111                         }
112                 } else usage();
113         }
114
115         if(!strcmp("",device)) {
116                 printf("you have to specify a device!\n");
117                 return -1;
118         }
119
120         /* open audio fd */
121         if(mode&RECORD) o_mode=O_RDONLY;
122         if(mode&PLAY) o_mode=O_WRONLY;
123         if(mode&RECORD && mode&PLAY) o_mode=O_RDWR;
124         if((audio_fd=open_sound_dev(device,o_mode))==-1) {
125                 printf("unable to open %s\n",device);
126                 return -1;
127         }
128
129         /* file fd's */
130         if((mode&PLAY) || (mode&CONVERT)) {
131                 if((pfile_fd=open_file(play_file,O_RDONLY))==-1) {
132                         printf("unable to open file %s for reading\n",play_file);
133                         return -1;
134                 }
135         }
136         if((mode&RECORD) || (mode&CONVERT)) {
137                 if((sfile_fd=open_file(record_file,O_CREAT|O_WRONLY))==-1) {
138                         printf("unable to open file %s for writing\n",record_file);
139                         return -1;
140                 }
141         }
142
143         if(print_info) {
144                 if(mode&PLAY) {
145                         printf("file info:\n");
146                         lseek(pfile_fd,4,SEEK_SET);
147                         read(pfile_fd,&info_int,4);
148                         printf("file size: %d\n",info_int);
149                         lseek(pfile_fd,8,SEEK_CUR);
150                         read(pfile_fd,&info_int,4);
151                         printf("fmtsize: %d\n",info_int);
152                         if(info_int==16) set.format=AFMT_S16_LE;
153                         if(info_int==8) set.format=AFMT_U8;
154                         read(pfile_fd,&info_int,4);
155                         printf("format tag: %d\n",info_int&0xffff);
156                         printf("channels: %d\n",(info_int>>16)&0xffff);
157                         set.channel=(info_int>>16)&0xffff;
158                         read(pfile_fd,&info_int,4);
159                         printf("samples/sec: %d\n",info_int);
160                         set.freq=info_int;
161                         read(pfile_fd,&info_int,4);
162                         printf("bytes/sec: %d\n",info_int);
163                         read(pfile_fd,&info_int,4);
164                         printf("block allign: %d\n",info_int&0xffff);
165                         printf("bits/sample: %d\n",(info_int>>16)&0xffff);
166                         lseek(pfile_fd,4,SEEK_CUR);
167                         read(pfile_fd,&info_int,4);
168                         printf("datasize: %d\n\n",info_int);
169                         /* return to start */
170                         lseek(pfile_fd,0,SEEK_SET);
171                 }
172         }
173
174         /* set dsp and get capabilities */
175         if(get_dsp_cap(audio_fd,&set,1)==-1) {
176                 printf("unable to get capabilities :(\n");
177                 return -1;
178         }
179         if(set_dsp(audio_fd,&set)==-1) {
180                 printf("unable to set dsp :(\n");
181                 return -1;
182         }
183
184         /* allocating buffer */
185         if((buf=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
186                 printf("allocating memory failed :(\n");
187                 perror("malloc");
188                 return -1;
189         }
190         if((mode&RECORD) && (mode&PLAY)) {
191                 if((buf2=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
192                         printf("allocating 2nd memory failed :(\n");
193                         perror("malloc");
194                         return -1;
195                 }
196         }
197
198         if((mode&PLAY) && (!(mode&RECORD))) {
199                 printf("playing file %s ...\n",play_file);
200                 rw=1;
201                 while(rw) {
202                         rw=read(pfile_fd,buf,set.bufsize);
203                         write(audio_fd,buf,set.bufsize);
204                 }
205         }
206
207         if((mode&RECORD) && (!(mode&PLAY))) {
208                 printf("recording to file %s ...\n",record_file);
209                 rw=1;
210                 while(rw) {
211                         rw=read(audio_fd,buf,set.bufsize);
212                         write(sfile_fd,buf,set.bufsize);
213                 }
214         }
215
216         if((mode&RECORD) && (mode&PLAY)) {
217                 FD_ZERO(&read_fds);
218                 FD_ZERO(&write_fds);
219                 /* read_fds */
220                 FD_SET(0,&read_fds);
221                 FD_SET(pfile_fd,&read_fds);
222                 FD_SET(audio_fd,&read_fds);
223                 /* write_fds */
224                 FD_SET(sfile_fd,&write_fds);
225                 FD_SET(audio_fd,&write_fds);
226                 fds_tv.tv_sec=0;
227                 fds_tv.tv_usec=1000;
228                 while(c!='q') {
229                         k=select(sfile_fd+1,&read_fds,&write_fds,NULL,&fds_tv);
230                         if(k==0) printf("itz zZzero :p\n");
231                         if(k) {
232                                 if(FD_ISSET(0,&read_fds)) {
233                                         puts("reading from stdin");
234                                         read(0,&c,1);
235                                 }
236                                 if(FD_ISSET(pfile_fd,&read_fds)) {
237                                         puts("read from sound file");
238                                         read(pfile_fd,buf2,set.bufsize);
239                                 }
240                                 if(FD_ISSET(audio_fd,&read_fds)) {
241                                         puts("reading from audio device");
242                                         read(audio_fd,buf,set.bufsize);
243                                 }
244                                 if(FD_ISSET(sfile_fd,&write_fds)) {
245                                         puts("writing to file");
246                                         write(sfile_fd,buf,set.bufsize);
247                                 }
248                                 if(FD_ISSET(audio_fd,&write_fds)) {
249                                         puts("writing to audio device");
250                                         write(audio_fd,buf2,set.bufsize);
251                                 }
252                         }
253                 }
254         }
255
256         if(mode&CONVERT) {
257                 if((tmp=lseek(pfile_fd,0,SEEK_END))==-1) {
258                         printf("cannot determine filesize :(\n");
259                         perror("lseek");
260                         return -1;
261                 }
262                 lseek(pfile_fd,0,SEEK_SET);
263                 strcpy(info,"RIFF");
264                 write(sfile_fd,info,4);
265                 info_int=tmp+36;
266                 write(sfile_fd,&info_int,4);
267                 strcpy(info,"WAVEfmt ");
268                 write(sfile_fd,info,8);
269                 if(set.format==AFMT_S16_LE) info_int=16;
270                 if(set.format==AFMT_U8) info_int=8;
271                 write(sfile_fd,&info_int,4);
272                 info_int=set.channel<<16;
273                 info_int|=1;
274                 write(sfile_fd,&info_int,4);
275                 info_int=set.freq;
276                 write(sfile_fd,&info_int,4);
277                 info_int=set.freq*set.channel;
278                 if(set.format==AFMT_S16_LE) info_int*=2;
279                 write(sfile_fd,&info_int,4);
280                 info_int=(set.channel*8)<<16;
281                 info_int|=set.channel;
282                 write(sfile_fd,&info_int,4);
283                 strcpy(info,"data");
284                 write(sfile_fd,info,4);
285                 info_int=tmp;
286                 write(sfile_fd,&info_int,4);
287                 /* write data now ... */
288                 for(j=0;j<tmp/set.bufsize;j++) {
289                         i=read(pfile_fd,buf,set.bufsize);
290                         k=write(sfile_fd,buf,set.bufsize);
291                         printf("read %d, wrote %d\n",i,k);
292                 }
293                 printf("\ndone ...\n");
294         }
295                         
296         return 1;
297 }