Mercurial > hg > constant-q-cpp
changeset 121:2375457f2876
More necessary code, some work on build scripts
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 15 May 2014 14:23:42 +0100 |
parents | 3fa7e938e7d4 |
children | edbec47f4a3d |
files | Makefile.inc src/CQInverse.cpp src/CQKernel.cpp src/ConstantQ.cpp src/dsp/Window.h src/dsp/nan-inf.h vamp/CQChromaVamp.cpp vamp/CQVamp.cpp vamp/CQVamp.h vamp/Pitch.cpp vamp/Pitch.h |
diffstat | 11 files changed, 337 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile.inc Thu May 15 12:29:30 2014 +0100 +++ b/Makefile.inc Thu May 15 14:23:42 2014 +0100 @@ -1,8 +1,9 @@ -LIB_DIR := cpp-qm-dsp +LIB_DIR := src +INC_DIR := cq +TEST_DIR := test VAMP_DIR := vamp -QMDSP_DIR ?= ../qm-dsp VAMPSDK_DIR ?= ../vamp-plugin-sdk PLUGIN_EXT ?= .so @@ -11,7 +12,7 @@ CC ?= gcc CFLAGS := $(CFLAGS) -CXXFLAGS := -I. -I$(VAMPSDK_DIR) -I$(QMDSP_DIR) $(CXXFLAGS) +CXXFLAGS := -I. -I$(VAMPSDK_DIR) -I$(INC_DIR) -I$(LIB_DIR) $(CXXFLAGS) LDFLAGS := $(LDFLAGS) PLUGIN_LDFLAGS := $(LDFLAGS) $(PLUGIN_LDFLAGS) @@ -19,26 +20,26 @@ PF_LDFLAGS := $(LDFLAGS) -lsndfile PLUGIN := cqvamp$(PLUGIN_EXT) -TEST := $(LIB_DIR)/test -PF := $(LIB_DIR)/processfile +TEST := $(TEST_DIR)/test +PF := $(TEST_DIR)/processfile -LIB_HEADERS := $(LIB_DIR)/CQBase.h $(LIB_DIR)/CQKernel.h $(LIB_DIR)/ConstantQ.h $(LIB_DIR)/CQSpectrogram.h $(LIB_DIR)/CQInverse.h +LIB_HEADERS := $(INC_DIR)/CQBase.h $(LIB_DIR)/CQKernel.h $(INC_DIR)/ConstantQ.h $(INC_DIR)/CQSpectrogram.h $(INC_DIR)/CQInverse.h LIB_SOURCES := $(LIB_DIR)/CQKernel.cpp $(LIB_DIR)/ConstantQ.cpp $(LIB_DIR)/CQSpectrogram.cpp $(LIB_DIR)/CQInverse.cpp -VAMP_HEADERS := $(VAMP_DIR)/CQVamp.h $(VAMP_DIR)/CQChromaVamp.h -VAMP_SOURCES := $(VAMP_DIR)/CQVamp.cpp $(VAMP_DIR)/CQChromaVamp.cpp $(VAMP_DIR)/libmain.cpp +VAMP_HEADERS := $(VAMP_DIR)/CQVamp.h $(VAMP_DIR)/CQChromaVamp.h $(VAMP_DIR)/Pitch.h +VAMP_SOURCES := $(VAMP_DIR)/CQVamp.cpp $(VAMP_DIR)/CQChromaVamp.cpp $(VAMP_DIR)/libmain.cpp $(VAMP_DIR)/Pitch.cpp HEADERS := $(LIB_HEADERS) $(VAMP_HEADERS) SOURCES := $(LIB_SOURCES) $(VAMP_SOURCES) OBJECTS := $(SOURCES:.cpp=.o) -TEST_SOURCES := $(LIB_DIR)/test.cpp +TEST_SOURCES := $(TEST_DIR)/test.cpp TEST_OBJECTS := $(TEST_SOURCES:.cpp=.o) $(OBJECTS) -PF_SOURCES := $(LIB_DIR)/processfile.cpp +PF_SOURCES := $(TEST_DIR)/processfile.cpp PF_OBJECTS := $(PF_SOURCES:.cpp=.o) $(OBJECTS) -LIBS := $(QMDSP_DIR)/libqm-dsp.a $(VAMPSDK_DIR)/libvamp-sdk.a -lpthread +LIBS := $(VAMPSDK_DIR)/libvamp-sdk.a -lpthread all: $(PLUGIN) $(TEST) $(PF) @@ -62,29 +63,15 @@ # DO NOT DELETE -cpp-qm-dsp/CQKernel.o: cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/ConstantQ.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -cpp-qm-dsp/ConstantQ.o: cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/CQSpectrogram.o: cpp-qm-dsp/CQSpectrogram.h cpp-qm-dsp/ConstantQ.h -cpp-qm-dsp/CQSpectrogram.o: cpp-qm-dsp/CQBase.h cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/CQInverse.o: cpp-qm-dsp/CQInverse.h cpp-qm-dsp/CQBase.h -cpp-qm-dsp/CQInverse.o: cpp-qm-dsp/CQKernel.h -vamp/CQVamp.o: vamp/CQVamp.h cpp-qm-dsp/CQSpectrogram.h -vamp/CQVamp.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -vamp/CQVamp.o: cpp-qm-dsp/CQKernel.h -vamp/CQChromaVamp.o: vamp/CQChromaVamp.h cpp-qm-dsp/CQSpectrogram.h -vamp/CQChromaVamp.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -vamp/CQChromaVamp.o: cpp-qm-dsp/CQKernel.h -vamp/libmain.o: vamp/CQVamp.h cpp-qm-dsp/CQSpectrogram.h -vamp/libmain.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -vamp/libmain.o: cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/test.o: cpp-qm-dsp/CQSpectrogram.h cpp-qm-dsp/ConstantQ.h -cpp-qm-dsp/test.o: cpp-qm-dsp/CQBase.h cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/processfile.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -cpp-qm-dsp/processfile.o: cpp-qm-dsp/CQKernel.h cpp-qm-dsp/CQInverse.h -cpp-qm-dsp/ConstantQ.o: cpp-qm-dsp/CQBase.h cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/CQSpectrogram.o: cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/CQBase.h -cpp-qm-dsp/CQSpectrogram.o: cpp-qm-dsp/CQKernel.h -cpp-qm-dsp/CQInverse.o: cpp-qm-dsp/CQBase.h cpp-qm-dsp/CQKernel.h -vamp/CQVamp.o: cpp-qm-dsp/CQSpectrogram.h cpp-qm-dsp/ConstantQ.h -vamp/CQVamp.o: cpp-qm-dsp/CQBase.h cpp-qm-dsp/CQKernel.h +src/CQKernel.o: src/CQKernel.h src/dsp/MathUtilities.h src/dsp/nan-inf.h +src/CQKernel.o: src/dsp/FFT.h src/dsp/Window.h +src/ConstantQ.o: src/CQKernel.h src/dsp/Resampler.h src/dsp/MathUtilities.h +src/ConstantQ.o: src/dsp/nan-inf.h src/dsp/FFT.h +src/CQInverse.o: src/dsp/Resampler.h src/dsp/MathUtilities.h +src/CQInverse.o: src/dsp/nan-inf.h src/dsp/FFT.h +vamp/CQVamp.o: vamp/CQVamp.h +vamp/CQChromaVamp.o: vamp/CQChromaVamp.h +vamp/libmain.o: vamp/CQVamp.h vamp/CQChromaVamp.h +cq/ConstantQ.o: cq/CQBase.h src/CQKernel.h +cq/CQSpectrogram.o: cq/ConstantQ.h cq/CQBase.h src/CQKernel.h +cq/CQInverse.o: cq/CQBase.h src/CQKernel.h
--- a/src/CQInverse.cpp Thu May 15 12:29:30 2014 +0100 +++ b/src/CQInverse.cpp Thu May 15 14:23:42 2014 +0100 @@ -31,9 +31,9 @@ #include "CQInverse.h" -#include "dsp/rateconversion/Resampler.h" -#include "maths/MathUtilities.h" -#include "dsp/transforms/FFT.h" +#include "dsp/Resampler.h" +#include "dsp/MathUtilities.h" +#include "dsp/FFT.h" #include <algorithm> #include <iostream>
--- a/src/CQKernel.cpp Thu May 15 12:29:30 2014 +0100 +++ b/src/CQKernel.cpp Thu May 15 14:23:42 2014 +0100 @@ -31,9 +31,9 @@ #include "CQKernel.h" -#include "maths/MathUtilities.h" -#include "dsp/transforms/FFT.h" -#include "base/Window.h" +#include "dsp/MathUtilities.h" +#include "dsp/FFT.h" +#include "dsp/Window.h" #include <cmath> #include <cassert>
--- a/src/ConstantQ.cpp Thu May 15 12:29:30 2014 +0100 +++ b/src/ConstantQ.cpp Thu May 15 14:23:42 2014 +0100 @@ -33,9 +33,9 @@ #include "CQKernel.h" -#include "dsp/rateconversion/Resampler.h" -#include "maths/MathUtilities.h" -#include "dsp/transforms/FFT.h" +#include "dsp/Resampler.h" +#include "dsp/MathUtilities.h" +#include "dsp/FFT.h" #include <algorithm> #include <iostream>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dsp/Window.h Thu May 15 14:23:42 2014 +0100 @@ -0,0 +1,172 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + Constant-Q library + Copyright (c) 2013-2014 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +#include <cmath> +#include <iostream> +#include <map> +#include <vector> + +enum WindowType { + RectangularWindow, + BartlettWindow, + HammingWindow, + HanningWindow, + BlackmanWindow, + BlackmanHarrisWindow, + + FirstWindow = RectangularWindow, + LastWindow = BlackmanHarrisWindow +}; + +/** + * Various shaped windows for sample frame conditioning, including + * cosine windows (Hann etc) and triangular and rectangular windows. + */ +template <typename T> +class Window +{ +public: + /** + * Construct a windower of the given type and size. + * + * Note that the cosine windows are periodic by design, rather + * than symmetrical. (A window of size N is equivalent to a + * symmetrical window of size N+1 with the final element missing.) + */ + Window(WindowType type, int size) : m_type(type), m_size(size) { encache(); } + Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); } + Window &operator=(const Window &w) { + if (&w == this) return *this; + m_type = w.m_type; + m_size = w.m_size; + encache(); + return *this; + } + virtual ~Window() { delete[] m_cache; } + + void cut(T *src) const { cut(src, src); } + void cut(const T *src, T *dst) const { + for (int i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i]; + } + + WindowType getType() const { return m_type; } + int getSize() const { return m_size; } + + std::vector<T> getWindowData() const { + std::vector<T> d; + for (int i = 0; i < m_size; ++i) { + d.push_back(m_cache[i]); + } + return d; + } + +protected: + WindowType m_type; + int m_size; + T *m_cache; + + void encache(); +}; + +template <typename T> +void Window<T>::encache() +{ + int n = m_size; + T *mult = new T[n]; + int i; + for (i = 0; i < n; ++i) mult[i] = 1.0; + + switch (m_type) { + + case RectangularWindow: + for (i = 0; i < n; ++i) { + mult[i] = mult[i] * 0.5; + } + break; + + case BartlettWindow: + if (n == 2) { + mult[0] = mult[1] = 0; // "matlab compatible" + } else if (n == 3) { + mult[0] = 0; + mult[1] = mult[2] = 2./3.; + } else if (n > 3) { + for (i = 0; i < n/2; ++i) { + mult[i] = mult[i] * (i / T(n/2)); + mult[i + n - n/2] = mult[i + n - n/2] * (1.0 - (i / T(n/2))); + } + } + break; + + case HammingWindow: + if (n > 1) { + for (i = 0; i < n; ++i) { + mult[i] = mult[i] * (0.54 - 0.46 * cos(2 * M_PI * i / n)); + } + } + break; + + case HanningWindow: + if (n > 1) { + for (i = 0; i < n; ++i) { + mult[i] = mult[i] * (0.50 - 0.50 * cos(2 * M_PI * i / n)); + } + } + break; + + case BlackmanWindow: + if (n > 1) { + for (i = 0; i < n; ++i) { + mult[i] = mult[i] * (0.42 - 0.50 * cos(2 * M_PI * i / n) + + 0.08 * cos(4 * M_PI * i / n)); + } + } + break; + + case BlackmanHarrisWindow: + if (n > 1) { + for (i = 0; i < n; ++i) { + mult[i] = mult[i] * (0.35875 + - 0.48829 * cos(2 * M_PI * i / n) + + 0.14128 * cos(4 * M_PI * i / n) + - 0.01168 * cos(6 * M_PI * i / n)); + } + } + break; + } + + m_cache = mult; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dsp/nan-inf.h Thu May 15 14:23:42 2014 +0100 @@ -0,0 +1,13 @@ + +#ifndef NAN_INF_H +#define NAN_INF_H + +#define ISNAN(x) (sizeof(x) == sizeof(double) ? ISNANd(x) : ISNANf(x)) +static inline int ISNANf(float x) { return x != x; } +static inline int ISNANd(double x) { return x != x; } + +#define ISINF(x) (sizeof(x) == sizeof(double) ? ISINFd(x) : ISINFf(x)) +static inline int ISINFf(float x) { return !ISNANf(x) && ISNANf(x - x); } +static inline int ISINFd(double x) { return !ISNANd(x) && ISNANd(x - x); } + +#endif
--- a/vamp/CQChromaVamp.cpp Thu May 15 12:29:30 2014 +0100 +++ b/vamp/CQChromaVamp.cpp Thu May 15 14:23:42 2014 +0100 @@ -31,9 +31,9 @@ #include "CQChromaVamp.h" -#include "cpp-qm-dsp/CQSpectrogram.h" +#include "cq/CQSpectrogram.h" -#include "base/Pitch.h" +#include "Pitch.h" #include <algorithm> #include <cstdio>
--- a/vamp/CQVamp.cpp Thu May 15 12:29:30 2014 +0100 +++ b/vamp/CQVamp.cpp Thu May 15 14:23:42 2014 +0100 @@ -31,7 +31,7 @@ #include "CQVamp.h" -#include "base/Pitch.h" +#include "Pitch.h" #include <algorithm> #include <cstdio>
--- a/vamp/CQVamp.h Thu May 15 12:29:30 2014 +0100 +++ b/vamp/CQVamp.h Thu May 15 14:23:42 2014 +0100 @@ -34,7 +34,7 @@ #include <vamp-sdk/Plugin.h> -#include "cpp-qm-dsp/CQSpectrogram.h" +#include "cq/CQSpectrogram.h" class ConstantQ;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/Pitch.cpp Thu May 15 14:23:42 2014 +0100 @@ -0,0 +1,63 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + Constant-Q library + Copyright (c) 2013-2014 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#include "Pitch.h" + +#include <math.h> + +float +Pitch::getFrequencyForPitch(int midiPitch, + float centsOffset, + float concertA) +{ + float p = float(midiPitch) + (centsOffset / 100); + return concertA * powf(2.0, (p - 69.0) / 12.0); +} + +int +Pitch::getPitchForFrequency(float frequency, + float *centsOffsetReturn, + float concertA) +{ + float p = 12.0 * (log(frequency / (concertA / 2.0)) / log(2.0)) + 57.0; + + int midiPitch = int(p + 0.00001); + float centsOffset = (p - midiPitch) * 100.0; + + if (centsOffset >= 50.0) { + midiPitch = midiPitch + 1; + centsOffset = -(100.0 - centsOffset); + } + + if (centsOffsetReturn) *centsOffsetReturn = centsOffset; + return midiPitch; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vamp/Pitch.h Thu May 15 14:23:42 2014 +0100 @@ -0,0 +1,52 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ +/* + Constant-Q library + Copyright (c) 2013-2014 Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the Centre for + Digital Music; Queen Mary, University of London; and Chris Cannam + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _PITCH_H_ +#define _PITCH_H_ + +/** + * Convert between musical pitch (i.e. MIDI pitch number) and + * fundamental frequency. + */ +class Pitch +{ +public: + static float getFrequencyForPitch(int midiPitch, + float centsOffset = 0, + float concertA = 440.0); + + static int getPitchForFrequency(float frequency, + float *centsOffsetReturn = 0, + float concertA = 440.0); +}; + + +#endif