1 | /*
|
---|
2 | =============================================================================
|
---|
3 | frqprom.c -- generate the frequency / pitch PROM for the Buchla 700
|
---|
4 | Written by: D.N. Lynx Crowe -- see VER below for version
|
---|
5 | =============================================================================
|
---|
6 | */
|
---|
7 |
|
---|
8 | #define VER "Version 12 - 1987-09-17" /* version ID string */
|
---|
9 |
|
---|
10 | #define DEBUGIT 0
|
---|
11 |
|
---|
12 | #include "stdio.h"
|
---|
13 | #include "math.h"
|
---|
14 | #include "stddefs.h"
|
---|
15 |
|
---|
16 | #define N (double)192.0 /* number of steps in the oscillator */
|
---|
17 | #define R (double)524288.0 /* number of steps in the phase angle */
|
---|
18 | #define C (double)10066000.0 /* clock frequency */
|
---|
19 |
|
---|
20 | #define RNC ((R*N)/C) /* frequency multiplier */
|
---|
21 |
|
---|
22 | #if DEBUGIT
|
---|
23 | #define FILEOUT "FRQPROM.PRN"
|
---|
24 | #else
|
---|
25 | #define FILEOUT "FRQPROM.MOT"
|
---|
26 | #endif
|
---|
27 |
|
---|
28 | #define NOTIFY1 10 /* frquency notification interval */
|
---|
29 | #define NOTIFY2 600 /* pitch notification interval */
|
---|
30 |
|
---|
31 | #define HILIMIT (double)16383.5
|
---|
32 |
|
---|
33 | extern int msrec();
|
---|
34 |
|
---|
35 | double p, q, s, t, inc, f;
|
---|
36 |
|
---|
37 | unsigned short tab[32768];
|
---|
38 | unsigned char otab[65536];
|
---|
39 |
|
---|
40 | int count, notify;
|
---|
41 |
|
---|
42 | FILE *fp;
|
---|
43 |
|
---|
44 | /* |
---|
45 |
|
---|
46 | */
|
---|
47 |
|
---|
48 | main()
|
---|
49 | {
|
---|
50 | register long i;
|
---|
51 |
|
---|
52 | printf("Buchla 700 Frequency / Pitch PROM Generator %s\n\n", VER);
|
---|
53 |
|
---|
54 | q = RNC;
|
---|
55 |
|
---|
56 | if (NULL EQ (fp = fopen(FILEOUT, "wa"))) { /* open output file */
|
---|
57 |
|
---|
58 | printf("ERROR: Unable to open [%s] for output.\n", FILEOUT);
|
---|
59 | exit(1);
|
---|
60 | }
|
---|
61 |
|
---|
62 | printf("Output on [%s]\n", FILEOUT);
|
---|
63 | printf("Using: R = %f, N = %f\n", R, N);
|
---|
64 | printf(" C = %f, (R*N)/C = %f\n\n", C, q);
|
---|
65 |
|
---|
66 | #if DEBUGIT
|
---|
67 | fprintf(fp, "Buchla 700 Frequency / Pitch PROM Generator %s\n\n", VER);
|
---|
68 | fprintf(fp, "Using: R = %f, N = %f\n", R, N);
|
---|
69 | fprintf(fp, " C = %f, (R*N)/C = %f\n\n", C, q);
|
---|
70 | fprintf(fp, "Frequency portion of PROM\n");
|
---|
71 | #endif
|
---|
72 |
|
---|
73 | for (i = 0; i < 65536; i++) /* preset table to saturation value */
|
---|
74 | tab[i] = 65535;
|
---|
75 |
|
---|
76 | /* generate the frequency portion of the table from 0.0 to 15.95 Hz */
|
---|
77 | /* using the formula: inc = f * ((R*N)/C) */
|
---|
78 |
|
---|
79 | printf("Generating frequency portion of PROM file\n");
|
---|
80 | notify = NOTIFY1;
|
---|
81 | count = notify;
|
---|
82 |
|
---|
83 | #if DEBUGIT
|
---|
84 | for (f = (double)0.0; f < (double)16.0; f += ((double)0.05 * (double)NOTIFY1)) {
|
---|
85 | #else
|
---|
86 | for (f = (double)0.0; f < (double)16.0; f += (double)0.05) {
|
---|
87 | #endif
|
---|
88 | inc = f * q;
|
---|
89 | i = (long)floor(f * 20.0);
|
---|
90 | tab[i] = floor(inc);
|
---|
91 |
|
---|
92 | #if DEBUGIT
|
---|
93 | fprintf(fp, "%5d 0x%04x %14.4f %14.4f\n",
|
---|
94 | i, tab[i], f, inc);
|
---|
95 | #endif
|
---|
96 |
|
---|
97 | if (++count GE notify) {
|
---|
98 |
|
---|
99 | count = 0;
|
---|
100 | printf(".");
|
---|
101 | }
|
---|
102 | }
|
---|
103 |
|
---|
104 | printf("\n");
|
---|
105 |
|
---|
106 | #if DEBUGIT
|
---|
107 | fprintf(fp, "\n\nPitch portion of PROM\n");
|
---|
108 | #endif
|
---|
109 | /* |
---|
110 |
|
---|
111 | */
|
---|
112 | /* generate the pitch portion of the table from 160.0 to HILIMIT cents */
|
---|
113 | /* according to the formula: inc = ((R*K*N)/C)*(2**(p/1200)) */
|
---|
114 |
|
---|
115 | printf("Generating pitch portion of PROM file\n");
|
---|
116 | notify = NOTIFY2;
|
---|
117 | count = notify;
|
---|
118 |
|
---|
119 | #if DEBUGIT
|
---|
120 | for (p = (double)160.0; p < HILIMIT; p += ((double)0.5 * (double)NOTIFY2)) {
|
---|
121 | #else
|
---|
122 | for (p = (double)160.0; p < HILIMIT; p += (double)0.5) {
|
---|
123 | #endif
|
---|
124 |
|
---|
125 | s = p / (double)1200.0; /* calculate the increment */
|
---|
126 | t = pow((double)2.0, s);
|
---|
127 | inc = (double)149.082 * t;
|
---|
128 |
|
---|
129 | if (inc GE 65536.0) /* saturate */
|
---|
130 | break;
|
---|
131 |
|
---|
132 | i = (long)floor((double)2.0 * p); /* stuff the table */
|
---|
133 | tab[i] = floor(inc);
|
---|
134 |
|
---|
135 | #if DEBUGIT
|
---|
136 | fprintf(fp, "%5d 0x%04x %14.4f %14.4f %14.4f %14.4f\n",
|
---|
137 | i, tab[i], p, s, t, inc);
|
---|
138 | #endif
|
---|
139 |
|
---|
140 | if (++count GE notify) {
|
---|
141 |
|
---|
142 | count = 0;
|
---|
143 | printf(".");
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | printf("\n");
|
---|
148 |
|
---|
149 | /* |
---|
150 |
|
---|
151 | */
|
---|
152 | /* output the table */
|
---|
153 |
|
---|
154 | #if !DEBUGIT
|
---|
155 |
|
---|
156 | printf("Splitting table into LS and MS bytes for output\n");
|
---|
157 |
|
---|
158 | for (i = 0; i < 32768; i++) { /* split into high and low bytes */
|
---|
159 |
|
---|
160 | otab[i] = tab[i] & 0x00FF; /* LS byte in low half */
|
---|
161 | otab[i + 32768L] = tab[i] >> 8; /* MS byte in high half */
|
---|
162 | }
|
---|
163 |
|
---|
164 | printf("Writing Motorola S-Records to [%s]\n", FILEOUT);
|
---|
165 | msrec(fp, 0L, 65536L, otab); /* output the table as S-Records */
|
---|
166 |
|
---|
167 | #endif
|
---|
168 |
|
---|
169 | fclose(fp); /* close the file */
|
---|
170 | printf("Program complete.\n"); /* say we're done */
|
---|
171 | exit(0); /* go away */
|
---|
172 | }
|
---|