2 * hdrec -- some sort of multi tracker (not right now, but in the future :p)
4 * author: hackbard@hackdaworld.dyndns.org
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
15 #include <sys/select.h>
17 #include <sys/soundcard.h>
33 printf("-h \t\t print this help\n");
34 printf("-i \t\t use/print file info\n");
35 printf("-R \t\t play reversed :)\n");
36 printf("-d <device> \t sound device (eg: /dev/dsp)\n");
37 printf("-r <file> \t record to <file>\n");
38 printf("-p <file> \t play from <file>\n");
39 printf("-s \t\t stereo\n");
40 printf("-m \t\t mono\n");
41 printf("-f <format> \t 1=8bit - 2=16bit (le)\n");
42 printf("-F <hz> \t frequency\n");
43 printf("-c <src> <dst> \t converts raw to wav (specify f/m,s/F)\n");
48 int main(int argc,char **argv) {
52 char device[MAX_C_DEVICE];
57 char record_file[MAX_C_FILE];
58 char play_file[MAX_C_FILE];
61 unsigned char *buf2=NULL;
62 unsigned char print_info=0;
63 unsigned char info[8];
67 fd_set read_fds,write_fds;
68 struct timeval fds_tv;
73 IDirectFBSurface *primary;
74 DFBSurfaceDescription dsc;
85 set.format=AFMT_S16_LE;
101 strcpy(record_file,argv[++i]);
105 strcpy(play_file,argv[++i]);
118 if(atoi(argv[i])==1) set.format=AFMT_U8;
119 if(atoi(argv[i])==2) set.format=AFMT_S16_LE;
122 set.freq=atoi(argv[++i]);
125 strncpy(device,argv[++i],MAX_C_DEVICE-1);
129 strcpy(play_file,argv[++i]);
130 strcpy(record_file,argv[++i]);
139 if(!strcmp("",device)) {
140 printf("you have to specify a device!\n");
145 if(mode&RECORD) o_mode=O_RDONLY;
146 if(mode&PLAY) o_mode=O_WRONLY;
147 if(mode&RECORD && mode&PLAY) o_mode=O_RDWR;
148 if((audio_fd=open_sound_dev(device,o_mode))==-1) {
149 printf("unable to open %s\n",device);
154 if((mode&PLAY) || (mode&CONVERT)) {
155 if((pfile_fd=open_file(play_file,O_RDONLY))==-1) {
156 printf("unable to open file %s for reading\n",play_file);
160 if((mode&RECORD) || (mode&CONVERT)) {
161 if((sfile_fd=open_file(record_file,O_CREAT|O_WRONLY))==-1) {
162 printf("unable to open file %s for writing\n",record_file);
169 printf("file info:\n");
170 lseek(pfile_fd,4,SEEK_SET);
171 read(pfile_fd,&info_int,4);
172 printf("file size: %d\n",info_int);
173 lseek(pfile_fd,8,SEEK_CUR);
174 read(pfile_fd,&info_int,4);
175 printf("fmtsize: %d\n",info_int);
176 if(info_int==16) set.format=AFMT_S16_LE;
177 if(info_int==8) set.format=AFMT_U8;
178 read(pfile_fd,&info_int,4);
179 printf("format tag: %d\n",info_int&0xffff);
180 printf("channels: %d\n",(info_int>>16)&0xffff);
181 set.channel=(info_int>>16)&0xffff;
182 read(pfile_fd,&info_int,4);
183 printf("samples/sec: %d\n",info_int);
185 read(pfile_fd,&info_int,4);
186 printf("bytes/sec: %d\n",info_int);
187 read(pfile_fd,&info_int,4);
188 printf("block allign: %d\n",info_int&0xffff);
189 printf("bits/sample: %d\n",(info_int>>16)&0xffff);
190 lseek(pfile_fd,4,SEEK_CUR);
191 read(pfile_fd,&info_int,4);
192 printf("datasize: %d\n\n",info_int);
193 /* return to start */
194 lseek(pfile_fd,0,SEEK_SET);
198 /* set dsp and get capabilities */
199 if(get_dsp_cap(audio_fd,&set,1)==-1) {
200 printf("unable to get capabilities :(\n");
203 if(set_dsp(audio_fd,&set)==-1) {
204 printf("unable to set dsp :(\n");
208 /* allocating buffer */
209 if((buf=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
210 printf("allocating memory failed :(\n");
215 if((mode&RECORD) && (mode&PLAY)) {
216 if((buf2=malloc(set.bufsize*sizeof(unsigned char)))==NULL) {
217 printf("allocating 2nd memory failed :(\n");
223 if((mode&PLAY) && (!(mode&RECORD))) {
226 DirectFBInit(&argc,&argv);
227 DirectFBCreate(&dfb);
228 dfb->SetCooperativeLevel(dfb,DFSCL_FULLSCREEN);
229 dsc.flags=DSDESC_CAPS;
230 dsc.caps=DSCAPS_PRIMARY|DSCAPS_FLIPPING;
231 dfb->CreateSurface(dfb,&dsc,&primary);
232 primary->GetSize(primary,&width,&height);
233 dprintf(1,"graphical equalizer dims: %dx%d\n",width,height);
234 primary->SetColor(primary,0x80,0x80,0xff,0xff);
235 //primary->Flip(primary,NULL,DSFLIP_WAITFORSYNC);
238 fourier_init(&fourier,1);
239 fourier.type=FWD|DFT;
241 fourier.data_len[0]=set.bufsize/(set.format&AFMT_S16_LE?4:2);
242 fourier_alloc_data(&fourier);
243 printf("debug: allocated size for %d samples to do dft\n",fourier.data_len[0]);
244 dx=8*width/fourier.data_len[0];
245 printf("debug: dx = %d ???\n",dx);
247 printf("playing file %s ...\n",play_file);
248 if(mode&REVERSED) printf("but we do it reversed!\n");
250 if(!(mode&REVERSED)) {
253 rw=read(pfile_fd,buf,set.bufsize);
254 /* do fourier trafo */
255 for(sample=0;sample<fourier.data_len[0];sample++) fourier.data[sample].r=*((signed short *)buf+(set.format&AFMT_S16_LE?2:1)*sample);
256 fourier_dft_1d(&fourier);
258 primary->Clear(primary,0,0,0,0xff);
259 a_f=dx*fourier.data_len[0]*440/set.freq;
260 primary->DrawLine(primary,a_f,height,a_f,0);
261 for(sample=0;sample<fourier.data_len[0]/8;sample++) primary->FillRectangle(primary,sample*dx,0,dx,height*sqrt(fourier.ftdata[sample].r*fourier.ftdata[sample].r+fourier.ftdata[sample].i*fourier.ftdata[sample].i)/0x7fff);
262 primary->Flip(primary,NULL,DSFLIP_WAITFORSYNC);
267 write(audio_fd,buf,set.bufsize);
271 read(pfile_fd,info,4);
272 if(!strncmp(info,"RIFF",4)) {
274 printf("\nassuming wav file according to header ...\n");
277 lseek(pfile_fd,0,SEEK_SET);
278 tmp=lseek(pfile_fd,0,SEEK_END);
279 // if(set.format==AFMT_U8) i=set.channel;
280 // if(set.format==AFMT_S16_LE) i=set.channel*2;
281 for(j=0;j<(tmp-i);j++) {
282 for(k=0;k<set.bufsize;k++) {
283 lseek(pfile_fd,tmp-(j+1)*set.bufsize+k,SEEK_SET);
284 read(pfile_fd,buf+k,1);
286 write(audio_fd,buf,set.bufsize);
291 primary->Release(primary);
296 if((mode&RECORD) && (!(mode&PLAY))) {
297 printf("recording to file %s ...\n",record_file);
300 rw=read(audio_fd,buf,set.bufsize);
301 write(sfile_fd,buf,set.bufsize);
305 if((mode&RECORD) && (mode&PLAY)) {
310 FD_SET(pfile_fd,&read_fds);
311 FD_SET(audio_fd,&read_fds);
313 FD_SET(sfile_fd,&write_fds);
314 FD_SET(audio_fd,&write_fds);
318 k=select(sfile_fd+1,&read_fds,&write_fds,NULL,&fds_tv);
319 if(k==0) printf("itz zZzero :p\n");
321 printf("returned after %ld usecs\n",1000-fds_tv.tv_usec);
322 if(FD_ISSET(0,&read_fds)) {
325 if(FD_ISSET(pfile_fd,&read_fds)) {
326 read(pfile_fd,buf2,set.bufsize);
328 if(FD_ISSET(audio_fd,&read_fds)) {
329 read(audio_fd,buf,set.bufsize);
331 if(FD_ISSET(sfile_fd,&write_fds)) {
332 write(sfile_fd,buf,set.bufsize);
334 if(FD_ISSET(audio_fd,&write_fds)) {
335 write(audio_fd,buf2,set.bufsize);
342 if((tmp=lseek(pfile_fd,0,SEEK_END))==-1) {
343 printf("cannot determine filesize :(\n");
347 lseek(pfile_fd,0,SEEK_SET);
349 write(sfile_fd,info,4);
351 write(sfile_fd,&info_int,4);
352 strcpy(info,"WAVEfmt ");
353 write(sfile_fd,info,8);
354 if(set.format==AFMT_S16_LE) info_int=16;
355 if(set.format==AFMT_U8) info_int=8;
356 write(sfile_fd,&info_int,4);
357 info_int=set.channel<<16;
359 write(sfile_fd,&info_int,4);
361 write(sfile_fd,&info_int,4);
362 info_int=set.freq*set.channel;
363 if(set.format==AFMT_S16_LE) info_int*=2;
364 write(sfile_fd,&info_int,4);
365 info_int=(set.channel*8)<<16;
366 info_int|=set.channel;
367 write(sfile_fd,&info_int,4);
369 write(sfile_fd,info,4);
371 write(sfile_fd,&info_int,4);
372 /* write data now ... */
373 for(j=0;j<tmp/set.bufsize;j++) {
374 i=read(pfile_fd,buf,set.bufsize);
375 k=write(sfile_fd,buf,set.bufsize);
376 printf("read %d, wrote %d\n",i,k);
378 printf("\ndone ...\n");