removed binary - added convert function
[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/soundcard.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <errno.h>
18
19 #include "oss_api.h"
20 #include "hdrec.h"
21
22 int usage(void) {
23         printf("usage:\n\n");
24         printf("-h \t\t print this help\n");
25         printf("-i \t\t use/print file info\n");
26         printf("-r <file> \t record to <file>\n");
27         printf("-p <file> \t play from <file>\n");
28         printf("-s \t\t stereo\n");
29         printf("-m \t\t mono\n");
30         printf("-f <format> \t 1=8bit - 2=16bit (le)\n");
31         printf("-F <hz> \t frequency\n");
32         printf("-c <src> <dst> \t converts raw to wav (specify f/m,s/F)\n");
33         
34         return 1;
35 }
36
37 int main(int argc,char **argv) {
38         int sfile_fd;
39         int pfile_fd;
40         int audio_fd;
41         char device[MAX_C_DEVICE];
42         int i,j,k;
43         int rw;
44         unsigned char mode=0;
45         int o_mode=0;
46         char record_file[MAX_C_FILE];
47         char play_file[MAX_C_FILE];
48         dsp_set set;
49         unsigned char *buf;
50         unsigned char print_info=0;
51         unsigned char info[8];
52         int info_int;
53         int tmp;
54
55         /* defaults */
56         strcpy(device,"");
57         set.format=AFMT_S16_LE;
58         set.freq=44100;
59         set.channel=STEREO;
60
61         /* read argv */
62         for(i=1;i<argc;i++) {
63                 if(argv[i][0]=='-') {
64                         switch(argv[i][1]) {
65                                 case 'h':
66                                         usage();
67                                         return 1;
68                                 case 'i':
69                                         print_info=1;
70                                         break;
71                                 case 'r':
72                                         mode=RECORD;
73                                         strcpy(record_file,argv[++i]);
74                                         break;
75                                 case 'p':
76                                         mode=PLAY;
77                                         strcpy(play_file,argv[++i]);
78                                         break;
79                                 case 's':
80                                         set.channel=STEREO;
81                                         break;
82                                 case 'm':
83                                         set.channel=MONO;
84                                         break;
85                                 case 'f':
86                                         i++;
87                                         if(atoi(argv[i])==1) set.format=AFMT_U8;
88                                         if(atoi(argv[i])==2) set.format=AFMT_S16_LE;
89                                         break;
90                                 case 'F':
91                                         set.freq=atoi(argv[++i]);
92                                         break;
93                                 case 'd':
94                                         strncpy(device,argv[++i],MAX_C_DEVICE-1);
95                                         break;
96                                 case 'c':
97                                         mode=CONVERT;
98                                         strcpy(play_file,argv[++i]);
99                                         strcpy(record_file,argv[++i]);
100                                         break;
101                                 default:
102                                         usage();
103                                         return -1;
104                         }
105                 } else usage();
106         }
107
108         if(!strcmp("",device)) {
109                 printf("you have to specify a device!\n");
110                 return -1;
111         }
112
113         /* open audio fd */
114         if(mode&RECORD) o_mode=O_RDONLY;
115         if(mode&PLAY) o_mode=O_WRONLY;
116         if(mode&RECORD && mode&PLAY) o_mode=O_RDWR;
117         if((audio_fd=open_sound_dev(device,o_mode))==-1) {
118                 printf("unable to open %s\n",device);
119                 return -1;
120         }
121
122         /* file fd's */
123         if((mode&PLAY) || (mode&CONVERT)) {
124                 if((pfile_fd=open_file(play_file,O_RDONLY))==-1) {
125                         printf("unable to open file %s for reading\n",play_file);
126                         return -1;
127                 }
128         }
129         if((mode&RECORD) || (mode&CONVERT)) {
130                 if((sfile_fd=open_file(record_file,O_CREAT|O_WRONLY))==-1) {
131                         printf("unable to open file %s for writing\n",record_file);
132                         return -1;
133                 }
134         }
135
136         if(print_info) {
137                 if(mode&PLAY) {
138                         printf("file info:\n");
139                         lseek(pfile_fd,4,SEEK_SET);
140                         read(pfile_fd,&info_int,4);
141                         printf("file size: %d\n",info_int);
142                         lseek(pfile_fd,8,SEEK_CUR);
143                         read(pfile_fd,&info_int,4);
144                         printf("fmtsize: %d\n",info_int);
145                         if(info_int==16) set.format=AFMT_S16_LE;
146                         if(info_int==8) set.format=AFMT_U8;
147                         read(pfile_fd,&info_int,4);
148                         printf("format tag: %d\n",info_int&0xffff);
149                         printf("channels: %d\n",(info_int>>16)&0xffff);
150                         set.channel=(info_int>>16)&0xffff;
151                         read(pfile_fd,&info_int,4);
152                         printf("samples/sec: %d\n",info_int);
153                         set.freq=info_int;
154                         read(pfile_fd,&info_int,4);
155                         printf("bytes/sec: %d\n",info_int);
156                         read(pfile_fd,&info_int,4);
157                         printf("block allign: %d\n",info_int&0xffff);
158                         printf("bits/sample: %d\n",(info_int>>16)&0xffff);
159                         lseek(pfile_fd,4,SEEK_CUR);
160                         read(pfile_fd,&info_int,4);
161                         printf("datasize: %d\n\n",info_int);
162                         /* return to start */
163                         lseek(pfile_fd,0,SEEK_SET);
164                 }
165         }
166
167         /* set dsp and get capabilities */
168         if(get_dsp_cap(audio_fd,&set,1)==-1) {
169                 printf("unable to get capabilities :(\n");
170                 return -1;
171         }
172         if(set_dsp(audio_fd,&set)==-1) {
173                 printf("unable to set dsp :(\n");
174                 return -1;
175         }
176
177         /* allocating buffer */
178         if((buf=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
179                 printf("allocating memory failed :(\n");
180                 perror("malloc");
181                 return -1;
182         }
183
184         if(mode&PLAY) {
185                 printf("playing file %s ...\n",play_file);
186                 rw=1;
187                 while(rw) {
188                         rw=read(pfile_fd,buf,set.bufsize);
189                         write(audio_fd,buf,set.bufsize);
190                 }
191         }
192
193         if(mode&RECORD) {
194                 printf("recording to file %s ...\n",record_file);
195                 rw=1;
196                 while(rw) {
197                         rw=read(audio_fd,buf,set.bufsize);
198                         write(sfile_fd,buf,set.bufsize);
199                 }
200         }
201
202         if(mode&CONVERT) {
203                 if((tmp=lseek(pfile_fd,0,SEEK_END))==-1) {
204                         printf("cannot determine filesize :(\n");
205                         perror("lseek");
206                         return -1;
207                 }
208                 lseek(pfile_fd,0,SEEK_SET);
209                 strcpy(info,"RIFF");
210                 write(sfile_fd,info,4);
211                 info_int=tmp+36;
212                 write(sfile_fd,&info_int,4);
213                 strcpy(info,"WAVEfmt ");
214                 write(sfile_fd,info,8);
215                 if(set.format==AFMT_S16_LE) info_int=16;
216                 if(set.format==AFMT_U8) info_int=8;
217                 write(sfile_fd,&info_int,4);
218                 info_int=set.channel<<16;
219                 info_int|=1;
220                 write(sfile_fd,&info_int,4);
221                 info_int=set.freq;
222                 write(sfile_fd,&info_int,4);
223                 info_int=set.freq*set.channel;
224                 if(set.format==AFMT_S16_LE) info_int*=2;
225                 write(sfile_fd,&info_int,4);
226                 info_int=(set.channel*8)<<16;
227                 info_int|=set.channel;
228                 write(sfile_fd,&info_int,4);
229                 strcpy(info,"data");
230                 write(sfile_fd,info,4);
231                 info_int=tmp;
232                 write(sfile_fd,&info_int,4);
233                 /* write data now ... */
234                 for(j=0;j<tmp/set.bufsize;j++) {
235                         i=read(pfile_fd,buf,set.bufsize);
236                         k=write(sfile_fd,buf,set.bufsize);
237                         printf("read %d, wrote %d\n",i,k);
238                 }
239                 printf("\ndone ...\n");
240         }
241                         
242         return 1;
243 }