2 * hdrec -- some sort of multi tracker (not right now, but in the future :p)
4 * author: hackbard@hackdaworld.dyndns.org
11 #include <sys/ioctl.h>
12 #include <sys/types.h>
14 #include <sys/select.h>
16 #include <sys/soundcard.h>
26 printf("-h \t\t print this help\n");
27 printf("-i \t\t use/print file info\n");
28 printf("-R \t\t play reversed :)\n");
29 printf("-d <device> \t sound device (eg: /dev/dsp)\n");
30 printf("-r <file> \t record to <file>\n");
31 printf("-p <file> \t play from <file>\n");
32 printf("-s \t\t stereo\n");
33 printf("-m \t\t mono\n");
34 printf("-f <format> \t 1=8bit - 2=16bit (le)\n");
35 printf("-F <hz> \t frequency\n");
36 printf("-c <src> <dst> \t converts raw to wav (specify f/m,s/F)\n");
41 int main(int argc,char **argv) {
45 char device[MAX_C_DEVICE];
50 char record_file[MAX_C_FILE];
51 char play_file[MAX_C_FILE];
54 unsigned char *buf2=NULL;
55 unsigned char print_info=0;
56 unsigned char info[8];
60 fd_set read_fds,write_fds;
61 struct timeval fds_tv;
66 set.format=AFMT_S16_LE;
82 strcpy(record_file,argv[++i]);
86 strcpy(play_file,argv[++i]);
99 if(atoi(argv[i])==1) set.format=AFMT_U8;
100 if(atoi(argv[i])==2) set.format=AFMT_S16_LE;
103 set.freq=atoi(argv[++i]);
106 strncpy(device,argv[++i],MAX_C_DEVICE-1);
110 strcpy(play_file,argv[++i]);
111 strcpy(record_file,argv[++i]);
120 if(!strcmp("",device)) {
121 printf("you have to specify a device!\n");
126 if(mode&RECORD) o_mode=O_RDONLY;
127 if(mode&PLAY) o_mode=O_WRONLY;
128 if(mode&RECORD && mode&PLAY) o_mode=O_RDWR;
129 if((audio_fd=open_sound_dev(device,o_mode))==-1) {
130 printf("unable to open %s\n",device);
135 if((mode&PLAY) || (mode&CONVERT)) {
136 if((pfile_fd=open_file(play_file,O_RDONLY))==-1) {
137 printf("unable to open file %s for reading\n",play_file);
141 if((mode&RECORD) || (mode&CONVERT)) {
142 if((sfile_fd=open_file(record_file,O_CREAT|O_WRONLY))==-1) {
143 printf("unable to open file %s for writing\n",record_file);
150 printf("file info:\n");
151 lseek(pfile_fd,4,SEEK_SET);
152 read(pfile_fd,&info_int,4);
153 printf("file size: %d\n",info_int);
154 lseek(pfile_fd,8,SEEK_CUR);
155 read(pfile_fd,&info_int,4);
156 printf("fmtsize: %d\n",info_int);
157 if(info_int==16) set.format=AFMT_S16_LE;
158 if(info_int==8) set.format=AFMT_U8;
159 read(pfile_fd,&info_int,4);
160 printf("format tag: %d\n",info_int&0xffff);
161 printf("channels: %d\n",(info_int>>16)&0xffff);
162 set.channel=(info_int>>16)&0xffff;
163 read(pfile_fd,&info_int,4);
164 printf("samples/sec: %d\n",info_int);
166 read(pfile_fd,&info_int,4);
167 printf("bytes/sec: %d\n",info_int);
168 read(pfile_fd,&info_int,4);
169 printf("block allign: %d\n",info_int&0xffff);
170 printf("bits/sample: %d\n",(info_int>>16)&0xffff);
171 lseek(pfile_fd,4,SEEK_CUR);
172 read(pfile_fd,&info_int,4);
173 printf("datasize: %d\n\n",info_int);
174 /* return to start */
175 lseek(pfile_fd,0,SEEK_SET);
179 /* set dsp and get capabilities */
180 if(get_dsp_cap(audio_fd,&set,1)==-1) {
181 printf("unable to get capabilities :(\n");
184 if(set_dsp(audio_fd,&set)==-1) {
185 printf("unable to set dsp :(\n");
189 /* allocating buffer */
190 if((buf=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
191 printf("allocating memory failed :(\n");
195 if((mode&RECORD) && (mode&PLAY)) {
196 if((buf2=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
197 printf("allocating 2nd memory failed :(\n");
203 if((mode&PLAY) && (!(mode&RECORD))) {
204 printf("playing file %s ...\n",play_file);
205 if(mode&REVERSED) printf("but we do it reversed!\n");
207 if(!(mode&REVERSED)) {
209 rw=read(pfile_fd,buf,set.bufsize);
210 write(audio_fd,buf,set.bufsize);
214 read(pfile_fd,info,4);
215 if(!strncmp(info,"RIFF",4)) {
217 printf("\nassuming wav file according to header ...\n");
220 lseek(pfile_fd,0,SEEK_SET);
221 tmp=lseek(pfile_fd,0,SEEK_END);
222 // if(set.format==AFMT_U8) i=set.channel;
223 // if(set.format==AFMT_S16_LE) i=set.channel*2;
224 for(j=0;j<(tmp-i);j++) {
225 for(k=0;k<set.bufsize;k++) {
226 lseek(pfile_fd,tmp-(j+1)*set.bufsize+k,SEEK_SET);
227 read(pfile_fd,buf+k,1);
229 write(audio_fd,buf,set.bufsize);
234 if((mode&RECORD) && (!(mode&PLAY))) {
235 printf("recording to file %s ...\n",record_file);
238 rw=read(audio_fd,buf,set.bufsize);
239 write(sfile_fd,buf,set.bufsize);
243 if((mode&RECORD) && (mode&PLAY)) {
248 FD_SET(pfile_fd,&read_fds);
249 FD_SET(audio_fd,&read_fds);
251 FD_SET(sfile_fd,&write_fds);
252 FD_SET(audio_fd,&write_fds);
256 k=select(sfile_fd+1,&read_fds,&write_fds,NULL,&fds_tv);
257 if(k==0) printf("itz zZzero :p\n");
259 printf("returned after %ld usecs\n",1000-fds_tv.tv_usec);
260 if(FD_ISSET(0,&read_fds)) {
263 if(FD_ISSET(pfile_fd,&read_fds)) {
264 read(pfile_fd,buf2,set.bufsize);
266 if(FD_ISSET(audio_fd,&read_fds)) {
267 read(audio_fd,buf,set.bufsize);
269 if(FD_ISSET(sfile_fd,&write_fds)) {
270 write(sfile_fd,buf,set.bufsize);
272 if(FD_ISSET(audio_fd,&write_fds)) {
273 write(audio_fd,buf2,set.bufsize);
280 if((tmp=lseek(pfile_fd,0,SEEK_END))==-1) {
281 printf("cannot determine filesize :(\n");
285 lseek(pfile_fd,0,SEEK_SET);
287 write(sfile_fd,info,4);
289 write(sfile_fd,&info_int,4);
290 strcpy(info,"WAVEfmt ");
291 write(sfile_fd,info,8);
292 if(set.format==AFMT_S16_LE) info_int=16;
293 if(set.format==AFMT_U8) info_int=8;
294 write(sfile_fd,&info_int,4);
295 info_int=set.channel<<16;
297 write(sfile_fd,&info_int,4);
299 write(sfile_fd,&info_int,4);
300 info_int=set.freq*set.channel;
301 if(set.format==AFMT_S16_LE) info_int*=2;
302 write(sfile_fd,&info_int,4);
303 info_int=(set.channel*8)<<16;
304 info_int|=set.channel;
305 write(sfile_fd,&info_int,4);
307 write(sfile_fd,info,4);
309 write(sfile_fd,&info_int,4);
310 /* write data now ... */
311 for(j=0;j<tmp/set.bufsize;j++) {
312 i=read(pfile_fd,buf,set.bufsize);
313 k=write(sfile_fd,buf,set.bufsize);
314 printf("read %d, wrote %d\n",i,k);
316 printf("\ndone ...\n");