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
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
#include <alsa/asoundlib.h>
#include <math.h>
/* TODO add support for 12, 14, 18 and 20, 22 kHz in addition to 16 kHz as well as custom frequencies */
/* TODO add support for selecting output device and backend */
/* TODO add support for selecting volume */
/* TODO add support for pausing and exiting */
#define UTYPE uint32_t
#define SMIN INT32_MIN
#define SMAX INT32_MAX
#define FORMAT SND_PCM_FORMAT_U32
#define SAMPLE_RATE 52000 /* Hz */
#define LATENCY 100000 /* µs */
USAGE("");
int
main(int argc, char *argv[])
{
UTYPE *buffer;
snd_pcm_uframes_t i, buflen = SAMPLE_RATE;
snd_pcm_sframes_t n;
snd_pcm_t *sound_handle = NULL;
unsigned long int freq = 16000;
double volume = (double)0.1f, imul, omul;
int r;
NOFLAGS(argc);
/* Set up audio */
r = snd_pcm_open(&sound_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (r < 0)
eprintf("snd_pcm_open: %s\n", snd_strerror(r));
if (!sound_handle)
eprintf("snd_pcm_open:");
/* Configure audio */
r = snd_pcm_set_params(sound_handle, FORMAT, SND_PCM_ACCESS_RW_INTERLEAVED, 1 /* channels */,
SAMPLE_RATE, 1 /* allow resampling? */, LATENCY);
if (r < 0)
eprintf("snd_pcm_set_params: %s\n", snd_strerror(r));
/* Generate tone */
buffer = emallocn((size_t)buflen, sizeof(*buffer), 0);
omul = volume * SMAX * 2;
imul = 2 * (double)freq / (double)SAMPLE_RATE;
#ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
#endif
imul *= M_PI;
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif
for (i = 0; i < buflen; i++)
buffer[i] = (UTYPE)(sin(imul * (double)i) * omul - SMIN);
/* Play tone */
for (;;) {
n = snd_pcm_writei(sound_handle, buffer, buflen);
if (n < 0)
n = snd_pcm_recover(sound_handle, (int)n, 0 /* do not print error reason? */);
if (n < 0)
eprintf("snd_pcm_writei: %s\n", snd_strerror((int)n));
if (n > 0 && (snd_pcm_uframes_t)n < buflen)
eprintf("short write from snd_pcm_writei\n");
}
snd_pcm_close(sound_handle);
return 0;
}
|