forked from fofix/fofix
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import the pypitch source code from the old upstream git.
- Loading branch information
Showing
8 changed files
with
720 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* pypitch - analyze audio streams for pitch | ||
* Copyright (C) 2009 John Stumpo | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/* $Id$ */ | ||
|
||
#include <Python.h> | ||
|
||
#include "AnalyzerInput.hpp" | ||
|
||
PyObject* feedAnalyzer(Analyzer* a, PyObject* instr) | ||
{ | ||
float* a_input; | ||
|
||
if (!PyString_Check(instr)) | ||
return PyErr_Format(PyExc_TypeError, "a string is required"); | ||
|
||
a_input = (float*)PyString_AsString(instr); | ||
a->input(a_input, a_input + (PyString_Size(instr) / sizeof(float))); | ||
|
||
Py_RETURN_NONE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* pypitch - analyze audio streams for pitch | ||
* Copyright (C) 2009 John Stumpo | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/* $Id$ */ | ||
|
||
#ifndef ANALYZERINPUT_HPP | ||
#define ANALYZERINPUT_HPP | ||
|
||
#include "pitch.hpp" | ||
|
||
PyObject* feedAnalyzer(Analyzer* a, PyObject* instr); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# pypitch - analyze audio streams for pitch | ||
# Copyright (C) 2008-2009 John Stumpo | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
__version__ = '$Id$' | ||
|
||
from _pypitch import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# pypitch - analyze audio streams for pitch | ||
# Copyright (C) 2008-2009 John Stumpo | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
__version__ = '$Id$' | ||
|
||
cdef extern from "vector": | ||
ctypedef struct _DoubleVector 'std::vector<double>': | ||
double (*get 'operator[]' )(int) nogil | ||
int (*size)() nogil | ||
|
||
cdef extern from "pitch.hpp": | ||
ctypedef struct _Tone 'const Tone': | ||
double freq | ||
double db | ||
double stabledb | ||
double* harmonics | ||
int age | ||
ctypedef struct _Analyzer 'Analyzer': | ||
void (*process)() nogil | ||
double (*getPeak)() nogil | ||
_DoubleVector (*getFormants)() nogil | ||
_Tone* (*findTone)(double, double) nogil | ||
_Analyzer* new_Analyzer 'new Analyzer' (double) nogil | ||
void delete_Analyzer 'delete' (_Analyzer*) nogil | ||
|
||
cdef extern from "AnalyzerInput.hpp": | ||
object feedAnalyzer(_Analyzer*, object) | ||
|
||
class Tone: | ||
def __init__(self, freq, db, stabledb, harmonics, age): | ||
self.freq = freq | ||
self.db = db | ||
self.stabledb = stabledb | ||
self.harmonics = harmonics | ||
self.age = age | ||
|
||
cdef object PyTone_FromTone(_Tone* t): | ||
cdef int i | ||
if t == NULL: | ||
return None | ||
harmonics = [] | ||
for 0 <= i < 8: | ||
harmonics.append(t.harmonics[i]) | ||
return Tone(t.freq, t.db, t.stabledb, harmonics, t.age) | ||
|
||
cdef class Analyzer: | ||
cdef _Analyzer* _this | ||
def __cinit__(self, double rate): | ||
self._this = new_Analyzer(rate) | ||
def __dealloc__(self): | ||
delete_Analyzer(self._this) | ||
def input(self, instr): | ||
if not typecheck(instr, str): | ||
instr = instr.tostring() # assume it was a numpy array | ||
return feedAnalyzer(self._this, instr) | ||
def process(self): | ||
self._this.process() | ||
def getPeak(self): | ||
return self._this.getPeak() | ||
def getFormants(self): | ||
cdef _DoubleVector v | ||
cdef int i | ||
cdef double cur | ||
v = self._this.getFormants() | ||
formants = [] | ||
for 0 <= i < v.size(): | ||
cur = v.get(i) | ||
if cur == 0.0: | ||
formants.append(None) | ||
else: | ||
formants.append(cur) | ||
return formants | ||
def findTone(self, double minfreq=70.0, double maxfreq=700.0): | ||
return PyTone_FromTone(self._this.findTone(minfreq, maxfreq)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* This file is copied from /libda/fft.hpp in the source code for Performous. | ||
* | ||
* Performous is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* Performous is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with Performous; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#ifndef AUDIO_FFT_HPP_INCLUDED | ||
#define AUDIO_FFT_HPP_INCLUDED | ||
|
||
/** | ||
@file fft.hpp FFT and related facilities. | ||
Header only, no need to link with libda. | ||
**/ | ||
|
||
#include <complex> | ||
#include <cstddef> | ||
|
||
namespace da { | ||
|
||
namespace math { | ||
|
||
/** Calculate the square of val. **/ | ||
static inline double sqr(double val) { return val * val; } | ||
|
||
template <unsigned M, unsigned N, unsigned B, unsigned A> struct SinCosSeries { | ||
static double value() { | ||
return 1 - sqr(A * M_PI / B) / M / (M+1) * SinCosSeries<M + 2, N, B, A>::value(); | ||
} | ||
}; | ||
template <unsigned N, unsigned B, unsigned A> struct SinCosSeries<N, N, B, A> { | ||
static double value() { return 1.0; } | ||
}; | ||
|
||
template <unsigned A, unsigned B> struct Sin { | ||
static double value() { return (A * M_PI / B) * SinCosSeries<2, 34, B, A>::value(); } | ||
}; | ||
|
||
template <unsigned A, unsigned B> struct Cos { | ||
static double value() { return SinCosSeries<1, 33, B, A>::value(); } | ||
}; | ||
|
||
/** Calculate sin(2 pi A / B). **/ | ||
template <unsigned A, unsigned B> double sin() { return Sin<A, B>::value(); } | ||
|
||
/** Calculate cos(2 pi A / B). **/ | ||
template <unsigned A, unsigned B> double cos() { return Cos<A, B>::value(); } | ||
} | ||
|
||
namespace fourier { | ||
// Based on the description of Volodymyr Myrnyy in | ||
// http://www.dspdesignline.com/showArticle.jhtml?printableArticle=true&articleId=199903272 | ||
template<unsigned P, typename T> struct DanielsonLanczos { | ||
static void apply(std::complex<T>* data) { | ||
const std::size_t N = 1 << P; | ||
const std::size_t M = N / 2; | ||
// Compute even and odd halves | ||
DanielsonLanczos<P - 1, T>().apply(data); | ||
DanielsonLanczos<P - 1, T>().apply(data + M); | ||
// Combine the results | ||
using math::sqr; | ||
using math::sin; | ||
const std::complex<T> wp(-2.0 * sqr(sin<1, N>()), -sin<2, N>()); | ||
std::complex<T> w(1.0); | ||
for (std::size_t i = 0; i < M; ++i) { | ||
std::complex<T> temp = data[i + M] * w; | ||
data[M + i] = data[i] - temp; | ||
data[i] += temp; | ||
w += w * wp; | ||
} | ||
} | ||
}; | ||
|
||
template<typename T> struct DanielsonLanczos<0, T> { static void apply(std::complex<T>*) {} }; | ||
} | ||
|
||
/** Perform FFT on data. **/ | ||
template<unsigned P, typename T> void fft(std::complex<T>* data) { | ||
// Perform bit-reversal sorting of sample data. | ||
const std::size_t N = 1 << P; | ||
std::size_t j = 0; | ||
for (std::size_t i = 0; i < N; ++i) { | ||
if (i < j) std::swap(data[i], data[j]); | ||
std::size_t m = N / 2; | ||
while (m > 1 && m <= j) { j -= m; m >>= 1; } | ||
j += m; | ||
} | ||
// Do the actual calculation | ||
fourier::DanielsonLanczos<P, T>::apply(data); | ||
} | ||
|
||
/** Perform FFT on data from floating point iterator, windowing the input. **/ | ||
template<unsigned P, typename InIt, typename Window> std::vector<std::complex<float> > fft(InIt begin, Window window) { | ||
std::vector<std::complex<float> > data(1 << P); | ||
// Perform bit-reversal sorting of sample data. | ||
const std::size_t N = 1 << P; | ||
std::size_t j = 0; | ||
for (std::size_t i = 0; i < N; ++i) { | ||
data[j] = *begin++ * window[i]; | ||
std::size_t m = N / 2; | ||
while (m > 1 && m <= j) { j -= m; m >>= 1; } | ||
j += m; | ||
} | ||
// Do the actual calculation | ||
fourier::DanielsonLanczos<P, float>::apply(&data[0]); | ||
return data; | ||
} | ||
|
||
} | ||
|
||
#endif | ||
|
Oops, something went wrong.