Chris@49: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@19: Chris@19: /* Chris@52: Sonic Visualiser Chris@52: An audio file viewer and annotation editor. Chris@52: Centre for Digital Music, Queen Mary, University of London. Chris@52: This file copyright 2006 Chris Cannam. Chris@19: Chris@52: This program is free software; you can redistribute it and/or Chris@52: modify it under the terms of the GNU General Public License as Chris@52: published by the Free Software Foundation; either version 2 of the Chris@52: License, or (at your option) any later version. See the file Chris@52: COPYING included with this distribution for more information. Chris@19: */ Chris@19: Chris@19: #ifndef _PITCH_H_ Chris@19: #define _PITCH_H_ Chris@19: Chris@19: #include Chris@19: Chris@19: class Pitch Chris@19: { Chris@19: public: Chris@274: /** Chris@274: * Return the frequency at the given MIDI pitch plus centsOffset Chris@274: * cents (1/100ths of a semitone). centsOffset does not have to Chris@274: * be in any particular range or sign. Chris@274: * Chris@274: * If concertA is non-zero, use that as the reference frequency Chris@274: * for the A at MIDI pitch 69; otherwise use the tuning frequency Chris@274: * specified in the application preferences (default 440Hz). Chris@274: */ Chris@1025: static double getFrequencyForPitch(int midiPitch, Chris@1025: double centsOffset = 0, Chris@1025: double concertA = 0.0); Chris@19: Chris@274: /** Chris@274: * Return the nearest MIDI pitch to the given frequency. Chris@274: * Chris@274: * If centsOffsetReturn is non-NULL, return in *centsOffsetReturn Chris@274: * the number of cents (1/100ths of a semitone) difference between Chris@274: * the given frequency and that of the returned MIDI pitch. The Chris@274: * cents offset will be in the range [-50,50). Chris@274: * Chris@274: * If concertA is non-zero, use that as the reference frequency Chris@274: * for the A at MIDI pitch 69; otherwise use the tuning frequency Chris@274: * specified in the application preferences (default 440Hz). Chris@274: */ Chris@1025: static int getPitchForFrequency(double frequency, Chris@1025: double *centsOffsetReturn = 0, Chris@1025: double concertA = 0.0); Chris@1025: Chris@1025: /** Chris@1025: * Compatibility version of getPitchForFrequency accepting float Chris@1025: * pointer argument. Chris@1025: */ Chris@1025: static int getPitchForFrequency(double frequency, Chris@1025: float *centsOffsetReturn, Chris@1025: double concertA = 0.0) { Chris@1025: double c; Chris@1025: int p = getPitchForFrequency(frequency, &c, concertA); Chris@1025: if (centsOffsetReturn) *centsOffsetReturn = float(c); Chris@1025: return p; Chris@1025: } Chris@19: Chris@274: /** Chris@373: * Return the nearest MIDI pitch range to the given frequency Chris@373: * range, that is, the difference in MIDI pitch values between the Chris@373: * higher and lower frequencies. Chris@373: * Chris@373: * If centsOffsetReturn is non-NULL, return in *centsOffsetReturn Chris@373: * the number of cents (1/100ths of a semitone) difference between Chris@373: * the given frequency difference and the returned MIDI pitch Chris@373: * range. The cents offset will be in the range [-50,50). Chris@373: * Chris@373: * If concertA is non-zero, use that as the reference frequency Chris@373: * for the A at MIDI pitch 69; otherwise use the tuning frequency Chris@373: * specified in the application preferences (default 440Hz). Chris@373: */ Chris@1025: static int getPitchForFrequencyDifference(double frequencyA, Chris@1025: double frequencyB, Chris@1025: double *centsOffsetReturn = 0, Chris@1025: double concertA = 0.0); Chris@373: Chris@373: /** Chris@1025: * Compatibility version of getPitchForFrequencyDifference Chris@1025: * accepting float pointer argument. Chris@1025: */ Chris@1025: static int getPitchForFrequencyDifference(double frequencyA, Chris@1025: double frequencyB, Chris@1025: float *centsOffsetReturn, Chris@1025: double concertA = 0.0) { Chris@1025: double c; Chris@1025: int p = getPitchForFrequencyDifference(frequencyA, frequencyB, Chris@1025: &c, concertA); Chris@1025: if (centsOffsetReturn) *centsOffsetReturn = float(c); Chris@1025: return p; Chris@1025: } Chris@1025: Chris@1025: /** Chris@1024: * Return the MIDI pitch for the given note number (0-12 where 0 Chris@1024: * is C) and octave number. The octave numbering system is based Chris@1024: * on the application preferences (default is C4 = middle C, Chris@1024: * though in previous SV releases that was C3). Chris@1024: */ Chris@1024: static int getPitchForNoteAndOctave(int note, int octave); Chris@1024: Chris@1024: /** Chris@1024: * Return the note number (0-12 where 0 is C) and octave number Chris@1024: * for the given MIDI pitch. The octave numbering system is based Chris@1024: * on the application preferences (default is C4 = middle C, Chris@1024: * though in previous SV releases that was C3). Chris@1024: */ Chris@1024: static void getNoteAndOctaveForPitch(int midiPitch, int ¬e, int &octave); Chris@1024: Chris@1024: /** Chris@274: * Return a string describing the given MIDI pitch, with optional Chris@892: * cents offset. This consists of the note name, octave number, Chris@892: * and optional cents. The octave numbering system is based on the Chris@892: * application preferences (default is C4 = middle C, though in Chris@892: * previous SV releases that was C3). Chris@274: * Chris@274: * For example, "A#3" (A# in octave 3) or "C2-12c" (C in octave 2, Chris@274: * minus 12 cents). Chris@274: * Chris@274: * If useFlats is true, spell notes with flats instead of sharps, Chris@274: * e.g. Bb3 instead of A#3. Chris@274: */ Chris@19: static QString getPitchLabel(int midiPitch, Chris@1025: double centsOffset = 0, Chris@26: bool useFlats = false); Chris@1023: Chris@274: /** Chris@274: * Return a string describing the nearest MIDI pitch to the given Chris@274: * frequency, with cents offset. Chris@274: * Chris@274: * If concertA is non-zero, use that as the reference frequency Chris@274: * for the A at MIDI pitch 69; otherwise use the tuning frequency Chris@274: * specified in the application preferences (default 440Hz). Chris@274: * Chris@274: * If useFlats is true, spell notes with flats instead of sharps, Chris@274: * e.g. Bb3 instead of A#3. Chris@274: */ Chris@1025: static QString getPitchLabelForFrequency(double frequency, Chris@1025: double concertA = 0.0, Chris@26: bool useFlats = false); Chris@274: Chris@274: /** Chris@373: * Return a string describing the given pitch range in octaves, Chris@373: * semitones and cents. This is in the form e.g. "1'2+4c". Chris@373: */ Chris@1025: static QString getLabelForPitchRange(int semis, double cents = 0); Chris@373: Chris@373: /** Chris@274: * Return true if the given frequency falls within the range of Chris@274: * MIDI note pitches, plus or minus half a semitone. This is Chris@274: * equivalent to testing whether getPitchForFrequency returns a Chris@274: * pitch in the MIDI range (0 to 127 inclusive) with any cents Chris@274: * offset. Chris@274: * Chris@274: * If concertA is non-zero, use that as the reference frequency Chris@274: * for the A at MIDI pitch 69; otherwise use the tuning frequency Chris@274: * specified in the application preferences (default 440Hz). Chris@274: */ Chris@1025: static bool isFrequencyInMidiRange(double frequency, Chris@1025: double concertA = 0.0); Chris@19: }; Chris@19: Chris@19: Chris@19: #endif