X-Git-Url: https://git.sesse.net/?p=pitch;a=blobdiff_plain;f=pitch.cpp;h=6ec6155cde18b4c479340d9cf824c6d705240c14;hp=3a04fa90c8d0f0dd55f81b5b80d4ade0d08d111b;hb=3fff09f828423670c99dac1681ef32c2f764dfea;hpb=24d0e4fa9a93f86fffd7bca85510973c97dc0dec diff --git a/pitch.cpp b/pitch.cpp index 3a04fa9..6ec6155 100644 --- a/pitch.cpp +++ b/pitch.cpp @@ -1,39 +1,20 @@ #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include "config.h" +#include "notes.h" +#include "linux_audio.h" #include "pitchdetector.h" -#define SAMPLE_RATE 22050 -#define FFT_LENGTH 4096 /* in samples */ -#define PAD_FACTOR 2 /* 1/pf of the FFT samples are real samples, the rest are padding */ -#define OVERLAP 4 /* 1/ol samples will be replaced in the buffer every frame. Should be - * a multiple of 2 for the Hamming window (see - * http://www-ccrma.stanford.edu/~jos/parshl/Choice_Hop_Size.html). - */ - -#define EQUAL_TEMPERAMENT 0 -#define WELL_TEMPERED_GUITAR 1 - -#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]; @@ -52,81 +33,10 @@ 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" }; - double half_notes_away = 12.0 * log2(freq / 440.0) - 3.0; + double half_notes_away = 12.0 * log2(freq / BASE_PITCH) - 3.0; int hnai = int(floor(half_notes_away + 0.5)); int octave = (hnai + 48) / 12; @@ -139,7 +49,7 @@ std::string freq_to_tonename(double freq) void print_spectrogram(double freq, double amp) { std::string notenames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; - double half_notes_away = 12.0 * log2(freq / 440.0) - 3.0; + double half_notes_away = 12.0 * log2(freq / BASE_PITCH) - 3.0; int hnai = int(floor(half_notes_away + 0.5)); int octave = (hnai + 48) / 12; @@ -168,19 +78,6 @@ void print_spectrogram(double freq, double amp) } #else -struct note { - char notename[16]; - double freq; -}; -static note notes[] = { - { "E-3", 110.0 * (3.0/4.0) }, - { "A-3", 110.0 }, - { "D-4", 110.0 * (4.0/3.0) }, - { "G-4", 110.0 * (4.0/3.0)*(4.0/3.0) }, - { "B-4", 440.0 * (3.0/4.0)*(3.0/4.0) }, - { "E-5", 440.0 * (3.0/4.0) } -}; - void print_spectrogram(double freq, double amp) { double best_away = 999999999.9;