8 #include <linux/soundcard.h>
10 #include "linux_audio.h"
12 int get_dsp_fd(int sample_rate, int fft_length, int overlap)
14 int fd = open("/dev/dsp", O_RDWR);
20 ioctl(3, SNDCTL_DSP_RESET, 0);
22 int fmt = AFMT_S16_LE; // FIXME
23 ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
26 ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &chan);
28 int rate = sample_rate;
29 ioctl(fd, SOUND_PCM_WRITE_RATE, &rate);
31 int max_fragments = 2;
32 int frag_shift = ffs(fft_length / overlap) - 1;
33 int fragments = (max_fragments << 16) | frag_shift;
34 ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments);
36 ioctl(3, SNDCTL_DSP_SYNC, 0);
42 void read_chunk(int fd, short *in, unsigned num_samples)
46 ret = read(fd, in, num_samples * sizeof(short));
52 if (ret != int(num_samples * sizeof(short))) {
59 // make a pure 440hz sine for testing
60 void read_chunk(int fd, short *in, unsigned num_samples)
62 static double theta = 0.0;
63 for (unsigned i = 0; i < num_samples; ++i) {
64 in[i] = 32768.0 * cos(theta);
65 theta += 2.0 * M_PI * 440.0 / double(SAMPLE_RATE);
70 void write_sine(int dsp_fd, double freq, unsigned num_samples, unsigned sample_rate)
72 static double theta = 0.0;
73 short buf[num_samples];
75 for (unsigned i = 0; i < num_samples; ++i) {
76 buf[i] = short(cos(theta) * 16384.0);
77 theta += 2.0 * M_PI * freq / double(sample_rate);
80 write(dsp_fd, buf, num_samples * sizeof(short));