1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/* tone.c - code for generating tones
* $Id: tone.c,v 1.5 2002/08/25 01:54:24 mgorse Exp $
*/
#include <errno.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include "es.h"
#ifdef EFLITE
#elif defined(__linux__)
#define LINUX_NATIVE
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/soundcard.h>
#else
#define DUMMY
#endif
#ifdef LINUX_NATIVE
static int speaker_tone(int freq, int dur)
{
int fd;
int converted_freq;
int result;
converted_freq = 1193180 / freq;
if (converted_freq == 0 || converted_freq > 0xffff) return 0;
fd = open("/dev/console", O_WRONLY);
if (fd == -1) return 0;
result = ioctl(fd, KDMKTONE, (dur << 16) + converted_freq);
close(fd);
return result;
}
#endif
#define PI 3.141592653589793238
#ifdef EFLITE
cst_wave *generate_tone(int freq, int dur, int vol)
{
float max = 2 * PI * freq * dur / 1000;
float step = 2 * PI * freq / 8000;
float n;
int i;
cst_wave *wptr;
wptr = cst_alloc(cst_wave, 1);
if (wptr == NULL) return wptr;
wptr->num_samples = max / step;
wptr->samples = cst_alloc(short, wptr->num_samples);
if (wptr->samples == NULL)
{
free(wptr);
return NULL;
}
wptr->num_channels = 1;
wptr->sample_rate = 8000;
for (i = 0,n = 0; i < wptr->num_samples; n += step,i++)
{
wptr->samples[i] = sin(n) * vol;
}
return wptr;
}
#endif /* EFLITE */
#ifdef LINUX_NATIVE
static int soundcard_tone(int freq, int dur, int vol)
{
int fd;
int fmt = AFMT_S16_LE;
int stereo = 0;
int speed = 44100;
float max = 2 * PI * freq * dur / 1000;
float step = 2 * PI * freq / speed;
float n;
short val;
fd = open("/dev/dsp", O_WRONLY);
if (fd == -1) return -1;
ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
ioctl(fd, SNDCTL_DSP_SPEED, &speed);
for (n = 0; n < max; n += step)
{
val = sin(n) * vol;
write(fd, &val, 2);
}
close(fd);
return 0;
}
#endif /* LINUX_NATIVE */
void do_tone(struct synth_struct *s, int freq, int dur, int vol, int flags)
{
#ifdef LINUX_NATIVE
if ((flags & 0x01) && !speaker_tone(freq, dur)) return;
if ((flags & 0x02) && !soundcard_tone(freq, dur, vol)) return;
#elif defined(EFLITE)
if (flags & 0x02) add_tone_command(s, freq, dur, vol);
#else
es_log(2, "tones not supported on this platform");
#endif
}
|