/* * mkcf.c * * @author Karen Orton * @copyright Karen Orton 2012 * * This program is part of an article in CQ-TV 235 entitled: * "A Compact Flash player for 405 Lines" * * To compile this program enter: * gcc -D_FILE_OFFSET_BITS=64 -Wall -o mkcf mkcf.c * **/ #include #include #define HRES 501 #define VRES 376 #define SECSZ 512 #define FLDSZ 256 #define AUDSZ 1620 #define VIDSTT 7 #define UCHAR unsigned char #define ULONG unsigned long typedef struct { UCHAR leftlo; UCHAR lefthi; UCHAR rightlo; UCHAR righthi; } AUDREC; typedef struct { UCHAR *plobyte; UCHAR *phibyte; int hinibble; } AUDVEC; AUDREC audbuf[AUDSZ]; AUDVEC audvector[AUDSZ]; UCHAR vidbuf[VRES][HRES]; UCHAR outbuf[2*FLDSZ][SECSZ]; FILE *vidfd, *audfd, *cffd; void genvector(); int doproc(); int main (int argc, char *argv[]) { int nframes; if(argc!=4) { fprintf(stderr, "\n\nusage: mkcf \n"); return 1; } if(!(vidfd=fopen(argv[1], "r"))) { fprintf(stderr, "\n\nmkcf: cannot open video file\n"); return 1; } if(!(audfd=fopen(argv[2], "r"))) { fclose(vidfd); fprintf(stderr, "\n\nmkcf: cannot open audio file\n"); return 1; } if(!(cffd=fopen(argv[3], "w"))) { fclose(vidfd); fclose(audfd); fprintf(stderr, "\n\nmkcf: cannot open CF file\n"); return 1; } genvector(); nframes=doproc(); fclose(vidfd); fclose(audfd); fclose(cffd); fprintf(stderr, "\n\nmkcf: total %d frames processed\n", nframes); return 0; } void genvector() { int i, j; AUDVEC *p; p=audvector; for(i=0; i<(VRES/2); i++) { p->plobyte=&outbuf[i][0]; p->phibyte=&outbuf[i][4]; p->hinibble=0; p++; p->plobyte=&outbuf[i][1]; p->phibyte=&outbuf[i][4]; p->hinibble=1; p++; p->plobyte=&outbuf[i][2]; p->phibyte=&outbuf[i][5]; p->hinibble=0; p++; p->plobyte=&outbuf[i][3]; p->phibyte=&outbuf[i][5]; p->hinibble=1; p++; } for(i=0; i<60; i++) { j=(VRES/2)-1-(2*i); p->plobyte=&outbuf[j-1][6]; p->phibyte=&outbuf[j][6]; p->hinibble=0; p++; } for(i=0; i<(VRES/2); i++) { j=i+FLDSZ; p->plobyte=&outbuf[j][0]; p->phibyte=&outbuf[j][4]; p->hinibble=0; p++; p->plobyte=&outbuf[j][1]; p->phibyte=&outbuf[j][4]; p->hinibble=1; p++; p->plobyte=&outbuf[j][2]; p->phibyte=&outbuf[j][5]; p->hinibble=0; p++; p->plobyte=&outbuf[j][3]; p->phibyte=&outbuf[j][5]; p->hinibble=1; p++; } for(i=0; i<56; i++) { j=FLDSZ+(VRES/2)-1-(2*i); p->plobyte=&outbuf[j-1][6]; p->phibyte=&outbuf[j][6]; p->hinibble=0; p++; } } int doproc() { int i, j, nframes, audexhausted; AUDREC *p; AUDVEC *q; ULONG audsmp; memset(outbuf, 0, sizeof(outbuf)); nframes=0; audexhausted=0; while(fread(vidbuf, HRES, VRES, vidfd)==VRES) { for(i=0; i<(VRES/2); i++) { j=i<<1; memcpy(&outbuf[i][VIDSTT], vidbuf[j], HRES); memcpy(&outbuf[i+FLDSZ][VIDSTT], vidbuf[j+1], HRES); } if((i=fread(audbuf, sizeof(AUDREC), AUDSZ, audfd))leftlo)+(((ULONG)p->lefthi)<<8)+((ULONG)p->rightlo)+(((ULONG)p->righthi)<<8); audsmp^=(((ULONG)(p->lefthi^p->righthi))<<9)&0x10000; *(q->plobyte)=(UCHAR)(audsmp>>5); if(q->hinibble) *(q->phibyte)|=(UCHAR)((audsmp>>9)&0xf0); else *(q->phibyte)=(UCHAR)((audsmp>>13)&0x0f); p++; q++; } fwrite(outbuf, SECSZ, 2*FLDSZ, cffd); nframes++; if((nframes%100)==0) fprintf(stderr, "mkcf: %d frames processed\n", nframes); } return nframes; }