Separate the Linux audio functions into a separate file.
authorsgunderson@bigfoot.com <>
Mon, 19 Jul 2010 21:18:58 +0000 (23:18 +0200)
committersgunderson@bigfoot.com <>
Mon, 19 Jul 2010 21:18:58 +0000 (23:18 +0200)
Makefile
linux_audio.cpp [new file with mode: 0644]
linux_audio.h [new file with mode: 0644]
pitch.cpp

index b98df23..9f3a83f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,9 @@ CPPFLAGS=
 
 all: pitch
 clean:
-       $(RM) pitch pitch.o pitchdetector.o
+       $(RM) pitch pitch.o pitchdetector.o linux_audio.o
 
-pitch: pitch.o pitchdetector.o
-       $(CXX) -o pitch pitch.o pitchdetector.o -lfftw3
+pitch: pitch.o pitchdetector.o linux_audio.o
+       $(CXX) -o pitch pitch.o pitchdetector.o linux_audio.o -lfftw3
 
 .PHONY: clean
diff --git a/linux_audio.cpp b/linux_audio.cpp
new file mode 100644 (file)
index 0000000..b76909e
--- /dev/null
@@ -0,0 +1,82 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+
+#include "linux_audio.h"
+
+int get_dsp_fd(int sample_rate, int fft_length, int overlap)
+{
+       int fd = open("/dev/dsp", O_RDWR);
+       if (fd == -1) {
+               perror("/dev/dsp");
+               exit(1);
+       }
+       
+       ioctl(3, SNDCTL_DSP_RESET, 0);
+       
+       int fmt = AFMT_S16_LE;   // FIXME
+       ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
+
+       int chan = 1;
+       ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &chan);
+       
+       int rate = sample_rate;
+       ioctl(fd, SOUND_PCM_WRITE_RATE, &rate);
+
+       int max_fragments = 2;
+       int frag_shift = ffs(fft_length / overlap) - 1;
+       int fragments = (max_fragments << 16) | frag_shift;
+        ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments);
+       
+       ioctl(3, SNDCTL_DSP_SYNC, 0);
+       
+       return fd;
+}
+
+#if 1
+void read_chunk(int fd, short *in, unsigned num_samples)
+{
+       int ret;
+
+       ret = read(fd, in, num_samples * sizeof(short));
+       if (ret == 0) {
+               printf("EOF\n");
+               exit(0);
+       }
+
+       if (ret != int(num_samples * sizeof(short))) {
+               // blah
+               perror("read");
+               exit(1);
+       }
+}
+#else
+// make a pure 440hz sine for testing
+void read_chunk(int fd, short *in, unsigned num_samples)
+{
+       static double theta = 0.0;
+       for (unsigned i = 0; i < num_samples; ++i) {
+               in[i] = 32768.0 * cos(theta);
+               theta += 2.0 * M_PI * 440.0 / double(SAMPLE_RATE);
+       }
+}
+#endif
+
+void write_sine(int dsp_fd, double freq, unsigned num_samples, unsigned sample_rate) 
+{
+       static double theta = 0.0;
+       short buf[num_samples];
+       
+       for (unsigned i = 0; i < num_samples; ++i) {
+               buf[i] = short(cos(theta) * 16384.0);
+               theta += 2.0 * M_PI * freq / double(sample_rate);
+       }
+
+       write(dsp_fd, buf, num_samples * sizeof(short));
+}
+
diff --git a/linux_audio.h b/linux_audio.h
new file mode 100644 (file)
index 0000000..e26da3d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LINUX_AUDIO_H
+#define _LINUX_AUDIO_H 1
+
+int get_dsp_fd(int sample_rate, int fft_length, int overlap);
+void read_chunk(int fd, short *in, unsigned num_samples);
+void write_sine(int dsp_fd, double freq, unsigned num_samples, unsigned sample_rate);
+
+#endif /* !defined(_LINUX_AUDIO_H) */
index 39e20ce..1ab4696 100644 (file)
--- a/pitch.cpp
+++ b/pitch.cpp
@@ -2,14 +2,8 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <complex>
-#include <cassert>
-#include <algorithm>
-#include <fftw3.h>
-#include <sys/ioctl.h>
-#include <linux/soundcard.h>
 
+#include "linux_audio.h"
 #include "pitchdetector.h"
 
 #define BASE_PITCH      440.0
 
 #define TUNING WELL_TEMPERED_GUITAR
 
-int get_dsp_fd();
-void read_chunk(int fd, short *in, unsigned num_samples);
 void print_spectrogram(double freq, double amp);
 void write_sine(int dsp_fd, double freq, unsigned num_samples);
 
 int main()
 {
        PitchDetector pd(SAMPLE_RATE, FFT_LENGTH, PAD_FACTOR, OVERLAP);
-       
-       int fd = get_dsp_fd();
+       int fd = get_dsp_fd(SAMPLE_RATE, FFT_LENGTH, OVERLAP);
        for ( ;; ) {
                short buf[FFT_LENGTH / PAD_FACTOR / OVERLAP];
 
@@ -54,77 +45,6 @@ int main()
        }
 }
 
-int get_dsp_fd()
-{
-       int fd = open("/dev/dsp", O_RDWR);
-       if (fd == -1) {
-               perror("/dev/dsp");
-               exit(1);
-       }
-       
-       ioctl(3, SNDCTL_DSP_RESET, 0);
-       
-       int fmt = AFMT_S16_LE;   // FIXME
-       ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
-
-       int chan = 1;
-       ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &chan);
-       
-       int rate = SAMPLE_RATE;
-       ioctl(fd, SOUND_PCM_WRITE_RATE, &rate);
-
-       int max_fragments = 2;
-       int frag_shift = ffs(FFT_LENGTH / OVERLAP) - 1;
-       int fragments = (max_fragments << 16) | frag_shift;
-        ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments);
-       
-       ioctl(3, SNDCTL_DSP_SYNC, 0);
-       
-       return fd;
-}
-
-#if 1
-void read_chunk(int fd, short *in, unsigned num_samples)
-{
-       int ret;
-
-       ret = read(fd, in, num_samples * sizeof(short));
-       if (ret == 0) {
-               printf("EOF\n");
-               exit(0);
-       }
-
-       if (ret != int(num_samples * sizeof(short))) {
-               // blah
-               perror("read");
-               exit(1);
-       }
-}
-#else
-// make a pure 440hz sine for testing
-void read_chunk(int fd, short *in, unsigned num_samples)
-{
-       static double theta = 0.0;
-       for (unsigned i = 0; i < num_samples; ++i) {
-               in[i] = 32768.0 * cos(theta);
-               theta += 2.0 * M_PI * 440.0 / double(SAMPLE_RATE);
-       }
-}
-#endif
-
-void write_sine(int dsp_fd, double freq, unsigned num_samples) 
-{
-       static double theta = 0.0;
-       short buf[num_samples];
-       
-       for (unsigned i = 0; i < num_samples; ++i) {
-               buf[i] = short(cos(theta) * 16384.0);
-               theta += 2.0 * M_PI * freq / double(SAMPLE_RATE);
-       }
-
-       write(dsp_fd, buf, num_samples * sizeof(short));
-}
-
 std::string freq_to_tonename(double freq)
 {
        std::string notenames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };