home *** CD-ROM | disk | FTP | other *** search
- /* fft_frequ.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include <kernel.h>
- #include <swis.h>
- /* #include "visdelay.h" */
- #include "fft.h"
-
-
- typedef struct {
- char name[12];
- float rate;
- unsigned int window;
- unsigned int nr_of_windows;
- } file_header;
-
- typedef struct {
- unsigned int draw;
- unsigned int version;
- unsigned int subversion;
- char creator[12];
- int low_x;
- int low_y;
- int hi_x;
- int hi_y;
- int misc[22];
- } DrawHeader;
-
- extern MCPower(float *a, float *b, int count);
- extern MCHanning(float *hanning, int n_data);
- int MakDraw(file_header fheader, float *in_data, char *draw_name, float s);
-
- int main(int argc, char *argv[]);
-
- int main(int argc, char *argv[])
- {
-
- float *real, *imag, *hanning, rate, scaleoffset;
- int m, n_data, tmp, type, offset;
- register int n;
- long int flen, ltmp;
- signed char schar;
- FILE *in;
- file_header header;
- _kernel_swi_regs reg;
- _kernel_oserror *err;
-
-
- if(argc != 5) {
- fprintf(stderr, "Usage: SampleFile DrawFile ZeroOffset ScalingFactor\n");
- exit(EXIT_FAILURE);
- }
- if((in = fopen(argv[1], "rb")) == NULL) {
- fprintf(stderr, "Cannot open %s for input\n", argv[1]);
- exit(EXIT_FAILURE);
- }
-
- reg.r[0] = 17;
- reg.r[1] = (int)argv[1];
- if((err=_kernel_swi(OS_File,®,®))!=NULL) {
- fprintf(stderr,"%s\n",err->errmess);
- exit(EXIT_FAILURE);
- }
-
- flen = reg.r[4];
- type = (reg.r[2] & 0xFFF00) >> 8;
-
- if(type != 0xD3C) {
- fprintf(stderr,"Input file must be an Armadeus one (0xD3C)\n");
- exit(EXIT_FAILURE);
- }
- offset = atoi(argv[3]);
- scaleoffset = atof(argv[4]);
- if(scaleoffset == 0) {
- fprintf(stderr,"You can't scale by 0, do you ?\n");
- exit(EXIT_FAILURE);
- }
-
- printf("Input : %s\nType : %X (Armadeus)\nLen : %ld\n\n",argv[1],type,flen);
- printf("Output: %s\nType : AFF (Draw)\n\n",argv[2]);
-
- tmp = 1;
- ltmp = flen-2;
- while(ltmp >>= 1) tmp++;
- m = tmp;
- n_data = 1;
- while(tmp--) n_data <<= 1;
-
- /* visdelay_init(); */
-
- if((real = malloc(sizeof(float) * n_data)) == NULL) {
- fprintf(stderr,"Cannot allocate %d bytes for real\n", sizeof(float) * n_data);
- exit(EXIT_FAILURE);
- }
- if((imag = malloc(sizeof(float) * n_data)) == NULL) {
- fprintf(stderr,"Cannot allocate %d bytes for imag\n", sizeof(float) * n_data);
- exit(EXIT_FAILURE);
- }
- if((hanning = malloc(sizeof(float) * n_data)) == NULL) {
- fprintf(stderr,"Cannot allocate %d bytes for hanning\n", sizeof(float) * n_data);
- exit(EXIT_FAILURE);
- }
-
- /* visdelay_begin(); */
-
- for(n=0; n<n_data; n++) {
- real[n] = 0;
- imag[n] = 0;
- }
-
- MCHanning(hanning, n_data);
-
- header.rate = (float)getc(in) * (float)1E-6;
- printf("Windowing ");
- if(offset != 0) {
- for(n=0; n<flen-1; n++) {
- schar = (signed char)getc(in);
- real[n] = (float)((int)schar + offset) * hanning[n];
- }
- }
- else {
- for(n=0; n<flen-1; n++) {
- schar = (signed char)getc(in);
- real[n] = (float)(schar) * hanning[n];
- }
- }
- fclose(in);
- printf("- Done\nComputing FFT ");
- fft2(real, imag, m-1);
- printf("- Done\nComputing power spectrum ");
- MCPower(real, imag, n_data>>1);
- printf("- Done\n");
- strcpy(header.name, "FFT_Frequ");
- /* header.rate = rate; */
- header.window = n_data >> 1;
- header.nr_of_windows = 1;
-
- free(hanning);
- free(imag);
- /* fwrite(&header, sizeof(file_header), 1, out); */
- /* fwrite(real, sizeof(float), n_data>>1, tmp); */
- printf("Building graph ");
- MakDraw(header, real, argv[2], scaleoffset);
- printf("- Done\n");
- /* fclose(out); */
-
- /* visdelay_end(); */
-
- return(0);
- }
-
- /*****************************************************************************/
-
- int MakDraw(file_header fheader, float *in_data, char *draw_name, float s)
- {
- FILE *out;
- DrawHeader header;
- unsigned int *buffer, buff_len;
- unsigned int paper_height, paper_width, usable_height, usable_width;
- unsigned int bottom_margin, left_margin, height, mm, point;
- unsigned int flen, ptr, start, end, tag_nr, tag_len;
- unsigned int x, x_origin, y, y_origin;
- int n, m;
-
- char tag_label[80], date[40];
- float y_max;
- double low_x, high_x, x_factor, y_factor, tag_step, nyquist;
-
- _kernel_swi_regs reg;
- _kernel_oserror *err;
-
-
-
- if((out=fopen(draw_name,"wb"))==NULL) {
- fprintf(stderr,"Cannot open %s for output\n", draw_name);
- exit(EXIT_FAILURE);
- }
-
- flen = fheader.window * fheader.nr_of_windows;
-
- buff_len = 3 * fheader.window * sizeof(int) + 51200;
- if((buffer=malloc(buff_len))==NULL) {
- fprintf(stderr,"Cannot allocate %d bytes for buffer\n",buff_len);
- exit(EXIT_FAILURE);
- }
- nyquist = 0.5 / (double)fheader.rate;
-
- header.draw = 0x77617244;
- header.version = 0x000000C9;
- header.subversion = 0x00000000;
- strcpy(header.creator,fheader.name);
- header.low_x = 0x00000000;
- header.low_y = 0x00000000;
- header.hi_x = 8 * 0xB400;
- header.hi_y = (unsigned int)(11.6 * 0xB400);
- header.misc[0] = 0x0000000B; /* object type 11 */
- header.misc[1] = 0x00000058; /* object size */
- header.misc[2] = 0x00000000;
- header.misc[3] = 0x00000000;
- header.misc[4] = 0x00000000;
- header.misc[5] = 0x00000000;
- header.misc[6] = 0x00000500; /* paper size */
- header.misc[7] = 0x00000101; /* grid default + portrait + limit shown */
- header.misc[8] = 0x3FF00000; /* gid spacing */
- header.misc[9] = 0x00000000;
- header.misc[10] = 0x00000002; /* grid division */
- header.misc[11] = 0x00000000; /* grid rectangular */
- header.misc[12] = 0x00000000; /* grid no auto adjust */
- header.misc[13] = 0x00000000; /* grid no show */
- header.misc[14] = 0x00000000; /* grid no lock */
- header.misc[15] = 0x00000001; /* grid cm */
- header.misc[16] = 0x00000001; /* zoom ratio numerator */
- header.misc[17] = 0x00000001; /* zoom ratio denominator */
- header.misc[18] = 0x00000000; /* no lock */
- header.misc[19] = 0x00000001; /* toolbox present */
- header.misc[20] = 0x00000080; /* select pre-selected */
- header.misc[21] = 0x00001388; /* undo buffer size */
- fwrite(&header, sizeof(DrawHeader), 1, out);
-
- ptr = 0;
- paper_width = 0x5A000;
- paper_height= 0x82800;
- height = (paper_width * 3) >> 2;
- bottom_margin = 0x5A00;
- left_margin = 0x16AE;
- mm = 1814;
- point = 640;
- y_max = 0;
- x_origin = left_margin + 10*mm;
- y_origin = bottom_margin + 10*mm;
- usable_width = paper_width - 20*mm - (left_margin<<1);
- usable_height = height - (y_origin<<1);
-
- #ifdef DEBUG
- fprintf(stderr,"usable_width: %u\n",usable_width);
- #endif
-
- /* horizontal line */
- start = ptr;
- buffer[ptr++] = 0x00000002; /* Path object */
- buffer[ptr++] = 0x00000044; /* object size */
- buffer[ptr++] = x_origin; /* bounding box low_x */
- buffer[ptr++] = y_origin; /* low_y */
- buffer[ptr++] = x_origin + usable_width; /* high_x */
- buffer[ptr++] = y_origin + 0; /* high_y */
- buffer[ptr++] = 0xFFFFFFFF; /* no fill */
- buffer[ptr++] = 0x00000000; /* outline colour */
- buffer[ptr++] = point >> 2; /* outline width 1/4 point */
- buffer[ptr++] = 0x20100042; /* style */
- buffer[ptr++] = 0x00000002; /* move to */
- buffer[ptr++] = x_origin; /* x */
- buffer[ptr++] = y_origin; /* y */
- buffer[ptr++] = 0x00000008; /* line to */
- buffer[ptr++] = x_origin + usable_width; /* x */
- buffer[ptr++] = y_origin + 0; /* y */
- buffer[ptr++] = 0x00000000; /* end path */
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
-
- /* vertical line */
- start = ptr;
- buffer[ptr++] = 0x00000002; /* Path object */
- buffer[ptr++] = 0x00000000; /* object size */
- buffer[ptr++] = x_origin; /* bounding box low_x */
- buffer[ptr++] = y_origin; /* low_y */
- buffer[ptr++] = x_origin + 0; /* high_x */
- buffer[ptr++] = y_origin + usable_height; /* high_y */
- buffer[ptr++] = 0xFFFFFFFF; /* no fill */
- buffer[ptr++] = 0x00000000; /* outline colour */
- buffer[ptr++] = point >> 2; /* outline width 1/4 point */
- buffer[ptr++] = 0x20100042; /* style */
- buffer[ptr++] = 0x00000002; /* move to */
- buffer[ptr++] = x_origin; /* x */
- buffer[ptr++] = y_origin; /* y */
- buffer[ptr++] = 0x00000008; /* line to */
- buffer[ptr++] = x_origin + 0; /* x */
- buffer[ptr++] = y_origin + usable_height; /* y */
- buffer[ptr++] = 0x00000000; /* end path */
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
-
- /* filename */
- reg.r[0] = 14;
- reg.r[1] = (int)date;
- date[0] = 0;
- if((err=_kernel_swi(OS_Word, ®, ®)) != NULL) {
- fprintf(stderr,"%s\n", err->errmess);
- exit(EXIT_FAILURE);}
-
- date[24] = ')';
- date[25] = '\0';
-
- sprintf(tag_label,"Name : %s (",draw_name);
- strcat(tag_label,date);
- tag_len = strlen(tag_label)+1;
- start = ptr;
- buffer[ptr++] = 0x00000001;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = x_origin;
- buffer[ptr++] = height - 8*mm - 0x2000;
- buffer[ptr++] = x_origin + tag_len*0x1000;
- buffer[ptr++] = height - 8*mm;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0xFFFFFF00;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0x00001000;
- buffer[ptr++] = 0x00002000;
- buffer[ptr++] = x_origin;
- buffer[ptr++] = height - 8*mm - 0x1C00;
- for(m=0; m<=tag_len/4; m++) buffer[ptr+m] = 0;
- strcpy((char *)(buffer+ptr),tag_label);
-
- ptr += tag_len / 4 + 1;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
-
-
- /* 100 Hz tags */
- tag_step = (100.0 * (double)usable_width) / nyquist;
- tag_nr = (unsigned int)((double)usable_width / tag_step);
-
- for(n=1; n<=tag_nr; n++) {
-
- low_x = tag_step * n;
- high_x = low_x;
-
- start = ptr;
- buffer[ptr++] = 0x00000002;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = x_origin + (unsigned int)low_x;
- buffer[ptr++] = y_origin - 1*mm;
- buffer[ptr++] = x_origin + (unsigned int)high_x;
- buffer[ptr++] = y_origin;
- buffer[ptr++] = 0xFFFFFFFF;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = point >> 2;
- buffer[ptr++] = 0x20100042;
- buffer[ptr++] = 0x00000002;
- buffer[ptr++] = x_origin + (unsigned int)low_x;
- buffer[ptr++] = y_origin - 1*mm;
- buffer[ptr++] = 0x00000008;
- buffer[ptr++] = x_origin + (unsigned int)high_x;
- buffer[ptr++] = y_origin;
- buffer[ptr++] = 0x00000000;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
- }
-
- /* 1000 Hz tags */
- tag_step = (1000.0 * (double)usable_width) / nyquist;
- tag_nr = (unsigned int)((double)usable_width / tag_step);
-
- for(n=0; n<=tag_nr; n++) {
- low_x = tag_step * n;
- high_x = low_x;
-
- start = ptr;
- buffer[ptr++] = 0x00000002;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = x_origin + (unsigned int)low_x;
- buffer[ptr++] = y_origin - 3*mm;
- buffer[ptr++] = x_origin + (unsigned int)high_x;
- buffer[ptr++] = y_origin;
- buffer[ptr++] = 0xFFFFFFFF;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = point >> 2;
- buffer[ptr++] = 0x20100042;
- buffer[ptr++] = 0x00000002;
- buffer[ptr++] = x_origin + (unsigned int)low_x;
- buffer[ptr++] = y_origin - 3*mm;
- buffer[ptr++] = 0x00000008;
- buffer[ptr++] = x_origin + (unsigned int)high_x;
- buffer[ptr++] = y_origin;
- buffer[ptr++] = 0x00000000;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
- }
-
- /* tag_label */
- for(n=0; n<=tag_nr; n++) {
- sprintf(tag_label,"%d",(int)((float)n*s));
- tag_len = strlen(tag_label);
- low_x = tag_step * n;
- high_x = low_x;
-
- start = ptr;
- buffer[ptr++] = 0x00000001;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = x_origin + (unsigned int)low_x - tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm - 0x2000;
- buffer[ptr++] = x_origin + (unsigned int)high_x + tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0xFFFFFF00;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0x00001000;
- buffer[ptr++] = 0x00001000;
- buffer[ptr++] = x_origin + (unsigned int)low_x - tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm - 0x1C00;
- for(m=0; m<=tag_len>>2; m++) buffer[ptr+m] = 0;
- strcpy((char *)(buffer+ptr),tag_label);
- ptr += (tag_len>>2) + 1;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
- }
-
- /* kHz */
- sprintf(tag_label,"kHz");
- tag_len = strlen(tag_label);
- low_x = tag_step * (tag_nr+1.0);
- high_x = low_x;
-
- start = ptr;
- buffer[ptr++] = 0x00000001;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = x_origin + (unsigned int)low_x - tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm - 0x2000;
- buffer[ptr++] = x_origin + (unsigned int)high_x + tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0xFFFFFF00;
- buffer[ptr++] = 0x00000000;
- buffer[ptr++] = 0x00001000;
- buffer[ptr++] = 0x00001000;
- buffer[ptr++] = x_origin + (unsigned int)low_x - tag_len*0x800;
- buffer[ptr++] = y_origin - 4*mm - 0x1C00;
- for(m=0; m<=tag_len>>2; m++) buffer[ptr+m] = 0;
- strcpy((char *)(buffer+ptr),tag_label);
- ptr += (tag_len>>2) + 1;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
- fwrite(buffer, sizeof(int), ptr, out);
- ptr=0;
-
- for(n=1; n<flen; n++) if(in_data[n] > y_max) y_max = in_data[n];
- y_factor = (double)usable_height / (double)y_max;
- x_factor = (double)usable_width / (double)flen;
-
- /* diagram */
- start = ptr;
- buffer[ptr++] = 0x00000002; /* Path object */
- buffer[ptr++] = 0x00000000; /* object size */
- buffer[ptr++] = x_origin; /* bounding box low_x */
- buffer[ptr++] = y_origin; /* low_y */
- buffer[ptr++] = x_origin; /* high_x */
- buffer[ptr++] = y_origin; /* high_y */
- buffer[ptr++] = 0xFFFFFFFF; /* no fill */
- buffer[ptr++] = 0x00000000; /* outline colour */
- buffer[ptr++] = 0x00000000; /*point >> 2;*/ /* outline width 1/4 point */
- buffer[ptr++] = 0x20100042; /* style */
- buffer[ptr++] = 0x00000002; /* move to */
- buffer[ptr++] = x_origin; /* x */
- buffer[ptr++] = y_origin; /* y */
-
- for(n=1; n<flen;n++) {
- buffer[ptr++] = 0x00000008; /* line to */
- x = x_origin + (unsigned int)((n-1.0)*x_factor);
- if(x>x_origin) buffer[start+4] = x;
- buffer[ptr++] = x; /* x */
- y = (int)((double)in_data[n] * y_factor) + y_origin;
- if(y>y_origin) buffer[start+5] = y;
- buffer[ptr++] = y; /* y */
- }
-
- buffer[ptr++] = 0x00000000;
- end = ptr;
- buffer[start+1] = (end-start) << 2;
-
-
-
- fwrite(buffer, sizeof(int), ptr, out);
- fclose(out);
-
- reg.r[0] = 18;
- reg.r[1] = (int)draw_name;
- reg.r[2] = 0xAFF;
- if((err=_kernel_swi(OS_File,®,®))!=NULL) {
- fprintf(stderr,"Error : %s\n",err->errmess);
- exit(EXIT_FAILURE);
- }
- /* os_swi3(8, 18, (int)draw_name, 0xAFF); */
-
- return(0);
- }
-
-