home *** CD-ROM | disk | FTP | other *** search
- /*
- * If the audio library or audio include files are missing, you need
- * to get /usr/demo/SOUND off the Sun OS tapes or CD.
- *
- * If FULLVOLUME is defined this routine will turn your audio device up to
- * full volume; it will not attempt to reset the current speaker / jack choice.
- *
- * The sun speaker has a residual "click" each time it switches from
- * silence to tone that I am unable to rid it of. The loudness of the "click"
- * varies from one sun model to another.
- */
-
- /* beepSun.c -- seligman 6/92 */
-
- /*
- -- Implementation of beep.h for Sun.
- -- Rick to Joe to Scott to Joe.
- */
-
- /* Date: Fri, 2 Aug 91 08:26:08 PDT */
- /* From: rick@st.unocal.com (Richard Ottolini) */
-
- /* Revised: Joe Dellinger */
- /* Sat Nov 28 02:30:32 HST 1992 */
-
- #include "beep.h"
- #include <sun/audioio.h>
- #include </usr/demo/SOUND/multimedia/libaudio.h>
- #include </usr/demo/SOUND/multimedia/ulaw2linear.h>
- #include <stropts.h>
- #include <math.h>
- #include <fcntl.h>
-
-
- #define RATE (8000) /* 8 K samples = 1 second */
- #define RAMP (RATE * 10 / 1000) /* 10 millisecond ramp */
- #define MAXTIME (2 * RATE) /* 2 seconds max tone time */
-
- static int audio;
- static audio_info_t audio_stat;
-
- int
- BeepInit ()
- {
- audio = open ("/dev/audio", O_WRONLY);
-
- if (audio < 0)
- /* Uh oh! */
- return 1;
- else
- {
- #ifdef FULLVOLUME
- /*
- * Turn the speaker (or headphone, whichever the user has it set to)
- * up to full volume.
- */
- ioctl (audio, AUDIO_GETINFO, &audio_stat);
- audio_stat.play.gain = AUDIO_MAX_GAIN;
- ioctl (audio, AUDIO_SETINFO, &audio_stat);
- #endif
-
- return 0;
- }
- }
-
-
- int
- Beep (time, volume, pitch)
- int time, volume, pitch;
- {
- static unsigned char silence[MAXTIME];
- static unsigned char soundbuf[MAXTIME - RAMP];
- static unsigned char ramp_down[RAMP];
- static int last_pitch = -1, last_n = -1, last_volume = -1;
- static int first_time = 1;
-
- int i, n, first_len, down_len, cycle;
- double dt;
-
- /*
- * Initialize the sound of silence
- */
- if (first_time == 1)
- {
- for (i = 0; i < MAXTIME; i++)
- silence[i] = (unsigned char) 0;
- first_time = 0;
- }
-
-
- /*
- * Finagle the number of samples
- */
- n = (time / 1000.) * RATE; /* Number samples in tone time */
- n = n < MAXTIME ? n : MAXTIME; /* clip to buffer size */
- n = n < 2 * RAMP ? 2 * RAMP : n; /* leave room for ramps */
-
- /*
- * Catch stupidity
- */
- if (pitch <= 0)
- volume = 0;
-
-
- if (volume <= 0)
- {
- write (audio, silence, n);
- }
- else
- {
- /*
- * clip to Nyquist
- * (Of course this means that if you ask for too high a frequency you
- * just get silence, since you sample all the zero-crossings of the
- * sine wave.)
- */
- pitch = pitch < RATE / 2 ? pitch : RATE / 2;
- cycle = ((RATE + 1.e-6) / pitch); /* samples per cycle */
-
- if (cycle > MAXTIME / 2)
- cycle = MAXTIME / 2;
-
- /* round down length of (rampup + mesa top) to integral cycle */
- first_len = ((n - RAMP) / cycle) * cycle;
- if (first_len < cycle)
- first_len = cycle;
- if (first_len > MAXTIME - RAMP)
- first_len = MAXTIME - RAMP;
-
- /* round down length of (rampdown) to integral cycle */
- down_len = ((RAMP) / cycle) * cycle;
- if (down_len < cycle)
- down_len = cycle;
- if (down_len > RAMP)
- down_len = RAMP;
-
- /*
- * Can we just reuse what we had before?
- */
- if (pitch != last_pitch || n > last_n || volume != last_volume)
- {
- last_pitch = pitch;
- last_n = n;
- last_volume = volume;
-
- dt = 2. * M_PI / cycle; /* sine scale factor */
-
- /* Ramp up; begin with silence */
-
- for (i = 0; i < RAMP; i++)
- {
- soundbuf[i] = audio_l2u (audio_d2l (
- ((float) i / RAMP) * (volume / 100.) * sin (i * dt)
- ));
- }
-
- /* Mesa top */
- for (i = RAMP; i < first_len; i++)
- {
- soundbuf[i] = audio_l2u (audio_d2l (
- 1. * (volume / 100.) * sin (i * dt)
- ));
- }
-
- /* Ramp down; end with silence */
- for (i = 0; i < down_len; i++)
- {
- ramp_down[i] = audio_l2u (audio_d2l (
- (1. - (float) (i + 1) / down_len) * (volume / 100.) * sin (i * dt)
- ));
- }
- }
-
- write (audio, soundbuf, first_len);
- write (audio, ramp_down, down_len);
- }
-
- return 0;
- }
-
-
- int
- BeepWait ()
- {
- ioctl (audio, AUDIO_DRAIN);
- return 0;
- }
-
-
- int
- BeepCleanup ()
- {
- return 0;
- }
-
-
- int
- BeepResume ()
- {
- return 0;
- }
-