#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <unistd.h>

extern char **environ;

/* #define DEBUG */
/* defines to control converstation */
#define SCALE 32768
#define CLIP 32635
#define BIAS 132
#define OFFSET 335
/* write sun header into U-law file */
#define writehdr(fp, ul) putc((ul >> 24) & 0xff, fp); \
putc((ul >> 16) & 0xff, fp); putc((ul >> 8) & 0xff, fp); \
putc(ul & 0xff, fp);

static void wr_header(FILE *optr, float frequency);

#define MAX_ENTRIES 10000

/* part of CGI struct */
typedef struct {
char *name;
char *val;
} entry;

/* defines for CGI input functions */
void getword(char *word, char *line, char stop);
int rind(char *s, char c);
int getline(char *s, int n, FILE *f);
void send_fd(FILE *f, FILE *fd);
char *makeword(char *line, char stop);
char *fmakeword(FILE *f, char stop, int *len);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);
void output_html(void);
void html_header(const char *htitle);
void html_footer(void);

void output_html(void)
{
printf("Content-type: text/html%c%c", 10, 10);
}

void html_header(const char *htitle)
{
printf("<html><head><title>%s</title></head>\n", htitle);
printf("<body>\n");
return;
}

void html_footer(void)
{
printf("</body></html>\n");
return;
}

main()
{
entry entries[MAX_ENTRIES];
int data_size, index, m;

float *ptr, *result, i, min, max, frequency, sample;
int count, *sigptr, *eptr, *mu;
FILE *fptr;

float temp;

output_html();
html_header("Test Sample");
data_size=atoi(getenv("CONTENT_LENGTH"));
/* printf("data_length=%d\n", data_size); */
/* reading inputs from test sample page */
for(index=0; data_size && (!feof(stdin)); index++){
m=index;
entries[index].val = fmakeword(stdin, '&', &data_size);
plustospace(entries[index].val);
unescape_url(entries[index].val);
entries[index].name = makeword(entries[index].val, '=');
}
printf("You submitted the following name/value pairs:<p>%c",10);
printf("<ul>%c",10);

for(index=0; index <= m; index++)
printf("<li> <code>%s = %s</code>%c",entries[index].name,
entries[index].val,10);
printf("</ul>%c",10);
/* convert sample inputs to float */
min=atof(entries[0].val);
max=atof(entries[1].val);
frequency=atof(entries[2].val);
sample=atof(entries[3].val);
/* calculate size of data points */
for(i=min, count=0; i <= max; i=i+sample){
#ifdef DEBUG
printf("i = %.2f\n", i);
#endif
count++;
}
#ifdef DEBUG
printf("size = %d\n", count);
#endif

/* allocate memory size */
ptr=(float *)malloc(count*sizeof(float));
result=(float *)malloc(count*sizeof(float));
sigptr=(int *)malloc(count*sizeof(int));
mu=(int *)malloc(count*sizeof(int));
eptr=(int *)malloc(count*sizeof(int));

if((ptr == NULL) || (sigptr == NULL) || (sigptr ==NULL) || (eptr == NULL)){
printf("Not enough memory!\n");
exit(1);
}
for(i=min, count=0; i <= max; i=i+sample, count++){
*(ptr+count) = sin(frequency * i);
#ifdef DEBUG
printf("sine of %f = %f\n", i, *(ptr+count));
#endif
}
for(i=min, count=0; i <= max; i=i+sample, count++){
*(ptr+count) = SCALE * *(ptr+count);
}
for(i=min, count=0; i <= max; i=i+sample, count++){
if((long)*(ptr+count) < 0)
*(sigptr+count) = -1;
else
*(sigptr+count) = 1;
}
#ifdef DEBUG
for(i=min, count=0; i <= max; i=i+sample, count++){
printf("sign=%d\n", *(sigptr+count));
}
for(i=min, count=0; i <= max; i=i+sample, count++){
printf("final = %f\n", *(ptr+count));
}
#endif
for(i=min, count=0; i <= max; i=i+sample, count++){
if(fabs(*(ptr+count)) > CLIP)
*(ptr+count) = CLIP;
else
*(ptr+count) = fabs(*(ptr+count));
}
for(i=min, count=0; i <= max; i=i+sample, count++){
*(result+count)=frexp((*(ptr+count)+BIAS), (eptr+count));
#ifdef DEBUG
printf("result=%f %d\n", *(result+count), *(eptr+count));
#endif
}

for(i=min, count=0; i <= max; i=i+sample, count++){
*(ptr+count)=64*(*(sigptr+count))-16*(*(eptr+count))-floor(32*(*
(result+count))) + OFFSET;
*(mu+count)=(long)*(ptr+count);
}
#ifdef DEBUG
for(i=min, count=0; i <= max; i=i+sample, count++){
printf("mu=%d\n", *(mu+count));
}
#endif
fptr=fopen("/tmp/tmp.au", "wb");
if(fptr == NULL){
printf("Unable to open file for write\n");
exit(1);
}
/* write sun header */
wr_header(fptr, frequency);
for(i=min, count=0; i <= max; i=i+sample, count++){
fwrite((mu+count),sizeof((mu+count)), count, fptr);
}
free(ptr);
free(sigptr);
free(result);
free(mu);
free(eptr);
printf("<a href=""../tmp.au"">Sound sample</a>\n");
html_footer();
}

static void wr_header(optr, frequency)
{
FILE *optr;
float frequency;
writehdr(optr, 0x2e736e64); /* Sun magic */
writehdr(optr, 24); /* header size in bytes */
writehdr(optr, ((unsigned)(~0))); /* unspecified data size */
writehdr(optr, 1); /* Sun uLaw format */
writehdr(optr, frequency); /* sample rate by definition :-) */
writehdr(optr, 1); /* single channel */
}


/* These part of the source file is from the CGI librarary */
#include <stdio.h>

#define LF 10
#define CR 13

void getword(char *word, char *line, char stop) {
int x = 0,y;

for(x=0;((line[x]) && (line[x] != stop));x++)
word[x] = line[x];

word[x] = '\0';
if(line[x]) ++x;
y=0;

while(line[y++] = line[x++]);
}

char *makeword(char *line, char stop) {
int x = 0,y;
char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));

for(x=0;((line[x]) && (line[x] != stop));x++)
word[x] = line[x];

word[x] = '\0';
if(line[x]) ++x;
y=0;

while(line[y++] = line[x++]);
return word;
}

char *fmakeword(FILE *f, char stop, int *cl) {
int wsize;
char *word;
int ll;

wsize = 102400;
ll=0;
word = (char *) malloc(sizeof(char) * (wsize + 1));

while(1) {
word[ll] = (char)fgetc(f);
if(ll==wsize) {
word[ll+1] = '\0';
wsize+=102400;
word = (char *)realloc(word,sizeof(char)*(wsize+1));
}
--(*cl);
if((word[ll] == stop) || (feof(f)) || (!(*cl))) {
if(word[ll] != stop) ll++;
word[ll] = '\0';
return word;
}
++ll;
}
}

char x2c(char *what) {
register char digit;

digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
return(digit);
}

void unescape_url(char *url) {
register int x,y;

for(x=0,y=0;url[y];++x,++y) {
if((url[x] = url[y]) == '%') {
url[x] = x2c(&url[y+1]);
y+=2;
}
}
url[x] = '\0';
}

void plustospace(char *str) {
register int x;

for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
}

int rind(char *s, char c) {
register int x;
for(x=strlen(s) - 1;x != -1; x--)
if(s[x] == c) return x;
return -1;
}

int getline(char *s, int n, FILE *f) {
register int i=0;

while(1) {
s[i] = (char)fgetc(f);

if(s[i] == CR)
s[i] = fgetc(f);

if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
s[i] = '\0';
return (feof(f) ? 1 : 0);
}
++i;
}
}

void send_fd(FILE *f, FILE *fd)
{
int num_chars=0;
char c;

while (1) {
c = fgetc(f);
if(feof(f))
return;
fputc(c,fd);
}
}

Go back to table of contents