home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------
- *
- * Generate a wave for use by the waveLAB program
- *
- * Written by Dave Tribby * All commercial rights reserved
- * (tribby@cup.hp.com) * Freeware: distribute, but not for profit.
- *
- * This program shows how to generate waveforms that can be used by waveLAB
- * in building additional waves. For waveLAB to use it, the file must have
- * these characteristics:
- *
- * - It consists of 1024 16-bit integers (65816 integer format).
- *
- * - Each integer is in the range 1 to 255 (high-order byte is 0).
- * The closer you can get the maximum value to 255, and the
- * minimum to 1, the better the resulting sound.
- *
- * - In order to reduce clicking and popping, try to have the wave
- * start and stop at the midpoint value, 128. In one example,
- * the code detects this mid-point and moves the wave values.
- *
- * - File name is "special1" or "special2" and is placed in the "@"
- * directory (either the one waveLAB is executed from or the user
- * directory on the file server).
- *
- * Hints...
- *
- * - If the wave can be reflected around a particular point, you only
- * need to generate part of the wave and then copy the results.
- *
- * - If a wave results in a sound that seems too soft, try working
- * with the inverse of the original values (256-y instead of y).
- *
- * - It may take several test runs to determine the starting and
- * stopping x-values that produce the best waveform. You can also
- * use a plotting program such as MathGraphics by Dirk Frohling
- * ($15 shareware) to select good ranges.
- *
- * The two examples are written so they could be easily moved individually
- * to separate programs.
- *
- * This program has been compiled under ORCA/C for the Apple IIGS.
- *
- * ---------------------------------------------------------------------
- */
-
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <orca.h>
-
- #pragma lint -1
- #pragma optimize -1
-
- #define BUILD_WAVE_SIZE 1024
- int *user_wave = NULL;
-
-
- /* --------------------------------------------------------------------- */
- /* Abnormal termination
- /* --------------------------------------------------------------------- */
- void AbEnd(char *msg)
- {
- int error;
- error = toolerror();
- fprintf(stderr, "\n%s:\n Tool error $%04X", msg, error);
- exit (-1);
- } /* AbEnd */
-
-
- /* -------------------------------------------------------------------- */
- /* Example 1:
- /* Create a non-symmetric wave that is known to start at a midpoint
- /* -------------------------------------------------------------------- */
-
- /* Range of X values (chosen such that f1()=128) */
- #define MinX1 -11.0
- #define MaxX1 4.1
-
- /* Function 1 (must return value in range 1-255) */
- /* Polynomial: 0.77*x*x*x + 8.0*x*x - 16.0*x + 8.5 */
- int f1(extended x)
- {
- /* Use parenthesized terms to reduce number of multiplies */
- return ((0.77*x + 8.0)*x - 16.0)*x + 8.5;
- }
-
- void GenerateWave1(char *wavename)
- {
- int i;
- int *pnt; /* Pointer into wave */
- extended x; /* Goes from -MaxX to +MaxX */
- extended x_step; /* Step for x values */
- extended slices; /* # elements as extended num */
- int min=256, max=0; /* Minumum and maximum Y values */
- FILE *userfile;
-
- /* Get the memory for the wave */
- if ( (user_wave = malloc(BUILD_WAVE_SIZE*2)) == NULL) {
- AbEnd("Allocating memory to hold wave");
- }
-
- fprintf(stderr, "Generating wave");
- slices = BUILD_WAVE_SIZE;
- x_step = (MaxX1-MinX1)/slices;
- x = MinX1;
- pnt = user_wave;
-
- for (i=0; i<=BUILD_WAVE_SIZE; i++) {
- *pnt = f1(x);
- /* Check for minimum and maximum */
- if ( (*pnt) < min ) min = *pnt;
- if ( (*pnt) > max ) max = *pnt;
- x += x_step;
- pnt++;
- if (i%100 == 0) fprintf(stderr, ".");
- }
-
- /* Write the file */
- userfile = fopen(wavename, "wb");
- (void) fwrite(user_wave, BUILD_WAVE_SIZE*2, 1, userfile);
- fclose(userfile);
-
- fprintf(stderr, " DONE!\n");
- fprintf(stderr, "Minimum value = %d; maximum = %d\n", min,max);
- if ( min < 1 )
- fprintf(stderr, "ERROR: minimum cannot be less than 1!\n");
- else if ( min != 1 )
- fprintf(stderr, "Note: for best results, minimum should be equal to 1\n");
- if ( max > 255 )
- fprintf(stderr, "ERROR: maximum cannot be greater than 255!\n");
- else if ( max != 255 )
- fprintf(stderr, "Note: for best results, maximum should be equal to 255\n");
- } /* GenerateWave1 */
-
-
-
-
- /* -------------------------------------------------------------------- */
- /* Example 2:
- /* Create a symmetric wave that does not start at a midpoint
- /* -------------------------------------------------------------------- */
-
- /* Range of X values goes from -MaxX2 to MaxX2 */
- #define MaxX2 6.23
-
- /* Function 2 (must return value in range 1-255) */
- int f2(extended x)
- {
- return 256 - cosh(x);
- }
-
- void GenerateWave2(char *wavename)
- {
- int i;
- int mp; /* Index of mid-point */
- int mpdelta; /* Diff between mp value and 128 */
- int *pnt, *pnt2; /* Pointer into waves */
- extended x; /* Goes from -MaxX2 to +MaxX2 */
- extended x_step; /* Step for x values */
- extended slices; /* # elements as extended num */
- int min=256, max=0; /* Minumum and maximum Y values */
- FILE *userfile;
-
- /* Get the memory for the wave */
- if ( (user_wave = malloc(BUILD_WAVE_SIZE*2)) == NULL) {
- AbEnd("Allocating memory to hold wave");
- }
-
- fprintf(stderr, "Generating wave");
- slices = BUILD_WAVE_SIZE;
- x_step = MaxX2*2/slices;
-
- pnt = user_wave;
-
- x = -MaxX2;
-
- /* Set up for mid-point search */
- mp = 0;
- mpdelta = abs(f2(x) - 128);
-
- /* Calculate first half of waveform */
- for (i=0; i<=(BUILD_WAVE_SIZE/2+1); i++) {
- *pnt = f2(x);
- /* Check for minimum and maximum */
- if ( (*pnt) < min ) min = *pnt;
- if ( (*pnt) > max ) max = *pnt;
-
- /* Check for mid-point (value is 128) */
- if ( abs(*pnt - 128) < mpdelta ) {
- mp = i;
- mpdelta = abs(*pnt - 128);
- }
- x += x_step;
- pnt++;
- if (i%100 == 0) fprintf(stderr, ".");
- }
-
- fprintf(stderr,"\nUsing mid-point at offset %d; y differs from 128 by %d\n",
- mp,mpdelta);
-
- /* Move values so mid-point (value=128) is on the end */
- pnt2 = user_wave;
- pnt = &user_wave[BUILD_WAVE_SIZE-mp];
- for (i=0; i<mp; i++) {
- *pnt = *pnt2;
- pnt++;
- pnt2++;
- }
- pnt = user_wave;
- for (i=mp; i<=(BUILD_WAVE_SIZE/2+1); i++) {
- *pnt = *pnt2;
- pnt++;
- pnt2++;
- }
-
- fprintf(stderr, "Reflecting...");
-
- /* Reflect first half onto second half */
- pnt2 = pnt--;
- for (i=0; i<BUILD_WAVE_SIZE/2; i++) {
- *pnt = *pnt2;
- pnt++;
- if (pnt2 == user_wave)
- pnt2=&user_wave[BUILD_WAVE_SIZE-1];
- else
- pnt2--;
- }
-
- /* Write the file */
- userfile = fopen(wavename, "wb");
- (void) fwrite(user_wave, BUILD_WAVE_SIZE*2, 1, userfile);
- fclose(userfile);
-
- fprintf(stderr, " DONE!\n");
- fprintf(stderr, "Minimum value = %d; maximum = %d\n", min,max);
- if ( min < 1 )
- fprintf(stderr, "ERROR: minimum cannot be less than 1!\n");
- else if ( min != 1 )
- fprintf(stderr, "Note: for best results, minimum should be equal to 1\n");
- if ( max > 255 )
- fprintf(stderr, "ERROR: maximum cannot be greater than 255!\n");
- else if ( max != 255 )
- fprintf(stderr, "Note: for best results, maximum should be equal to 255\n");
- } /* GenerateWave2 */
-
-
-
- /* -------------------------------------------------------------------- */
- /* Beginning of main program */
- /* -------------------------------------------------------------------- */
- int main (int argc, char *argv[])
- {
- fprintf(stderr, "Program to show how to create base waves for waveLAB\n");
-
- fprintf(stderr, "\nExample wave 1: polynomial\n");
- GenerateWave1("@:special1");
-
- fprintf(stderr, "\n\nExample wave 2: symmetric\n");
- GenerateWave2("@:special2");
- }
-