These python functions in c++? [closed]

旧街凉风 提交于 2019-12-11 05:07:47

问题


I basically have some source-code(not my own) in python that I would like to understand. It's an anti-aliased xor audio oscillator. I don't know python at all - but it's quite readable except for a few things:

Firstly - the full code:

f0 = 500.
fs = 44100.
T0 = f0/fs
P0 = fs/f0

t = arange(0,3*fs)
L = len(t)
imax = 2**16


# =============================================================================
# SIGNALS
# =============================================================================

# -----------------------------------------------------------------------------
#
def trivial_xor():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):
        d1 = 2*p - 1
        if p < w:   d2 = 0
        else:           d2 = -0.5
        x1 = int(d1 * imax) & 0xFFFF
        x2 = int(d2 * imax) & 0xFFFF
        y = (x1 ^ x2) / float(imax)
        s[n] = 2*y - 1
        sd1[n] = d1
        sd2[n] = d2
        p += T0
        if p > 1: p -= 1
    return s

# -----------------------------------------------------------------------------
#
def trivial_xor_withSources():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):
        d1 = 2*p - 1
        if p < w:   d2 = 0
        else:           d2 = -0.5
        x1 = int(d1 * imax) & 0xFFFF
        x2 = int(d2 * imax) & 0xFFFF
        y = (x1 ^ x2) / float(imax)
        s[n] = 2*y - 1
        sd1[n] = d1
        sd2[n] = d2
        p += T0
        if p > 1: p -= 1
    return s,sd1,sd2

# -----------------------------------------------------------------------------
#
def PTR1_xor():
    s = trivial_xor() - 2*T0
    #
    T1 = 2*T0
    P1 = 1/T1
    cdc = 1 + T1
    p0 = p1 = 0
    #
    for n in range(0,L):
        if p0 < 0.5:
            h = 0.5
            if p1 < T1:
                s[n] = p1*(2 - 2*h*P1) + 2*h - cdc
        elif p0 < 0.75:
            h = 0.5
            if p1 < T1:
                s[n] = p1*(2 - 2*h*P1) + 2*h - cdc + 1
        else:
            h = 1
            pp = p1 - 0.5
            if pp < T1:
                s[n] = pp*(2 - 2*h*P1) + 2*h - cdc
        #
        p0 += T0
        p1 += T1
        if p0 > 1:  p0 -= 1
        if p1 > 1:  p1 -= 1
    return s

It all seems pretty straight forward - except for what I assume to be the buffers, all I need to know is what is these function(s) in c++?

////////////////////////////////

t = arange(0,3*fs)
L = len(t)
imax = 2**16

////////////////////////////////

 def trivial_xor_withSources():
    s = zeros(L)
    sd1 = zeros(L)
    sd2 = zeros(L)
    s = zeros(L)
    w = 0.5
    p = 0
    for n in range(0,L):

I'm planning on using this in real time. The rest just look like simple math. Any help greatly appreciated!

Andrew


回答1:


If you're trying to convert the code to C++, you can easily implement a (roughly) equivalent arange function:

#include <vector>

template<typename T>
std::vector<T> arange(T start, T stop, T step = 1) {
    std::vector<T> values;
    for (T value = start; value < stop; value += step)
        values.push_back(value);
    return values;
}

You could then use it like this:

auto t = arange<double>(0, 3*fs);
auto L = t.length();

The ** is exponentiation. You could call the pow function:

#include <cmath>
const double imax = pow(2., 16.);

But since you are dealing with constants anyway, you would be better off with:

const double imax = 65536.;

If you want to retain the expressive power of 2**16 and you don't want to incur the run-time cost of calling pow (perhaps you want to be able to change the exponent without having to manually recalculate the constant), you can use a constexpr function:

constexpr unsigned long power(unsigned long base, unsigned long exponent) {
    return exponent == 0 ? 1 : base * pow(base, exponent - 1);
}

const unsigned long imax = power(2, 16);



回答2:


Here is an explanation for all the non-trivials lines you outlined:

  • len(t) means "length of t", that is to say, the number of elements in array t.

  • 2**16 is "two to the power of 16" (1 << 16 in your C++ code).

  • for n in range(0,L) is equivalent to for (int n = 0; i < L; ++i)

  • arange and zeros are likely Numpy functions. You can find reference for them here and here.

Regarding the last point, probably there is some import statement you omitted from the code.

Quoting from the docs:

arange

Return evenly spaced values within a given interval.

Values are generated within the half-open interval [start, stop) (in other words, the interval including start but excluding stop).

The default step is 1, so t will be an array containing numbers [0, 1, 2, 3, ..., 3 * 44100 - 1].

zeros

Return a new array of given shape and type, filled with zeros.

Default type for zeros is float, so s, sd1 and sd2 are initialized as arrays filled of 0.0, each having L elements.




回答3:


Python: t = arange(0,3*fs)

C++: double t[] = {0.0,1.0,...,3*fs}; // will not compile of course

Python: L = len(t)

C++: int L = sizeof(t)/sizeof(*t); // where t is an array in the current scope

Python: s = zeros(L)

C++: double s[L] = {0}; // where L is a constant

Python: for n in range(0,L)

C++: for (int i=0; i<L; i++)



来源:https://stackoverflow.com/questions/21216909/these-python-functions-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!