У меня в основном есть некоторый исходный код (не мой) на python, который я хотел бы понять. Это сглаженный аудио генератор xor. Я вообще не знаю Python, но он вполне читабелен, за исключением нескольких вещей:
Во-первых — полный код:
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
Все это кажется довольно простым — за исключением того, что я предполагаю как буферы, все, что мне нужно знать, это что это за функция (и) в 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):
Я планирую использовать это в режиме реального времени. Остальные просто выглядят как простая математика. Любая помощь с благодарностью!
Эндрю
Если вы пытаетесь преобразовать код в C ++, вы можете легко реализовать (примерно) эквивалент arange
функция:
#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;
}
Затем вы можете использовать это так:
auto t = arange<double>(0, 3*fs);
auto L = t.length();
**
это возведение в степень. Вы могли бы позвонить pow
функция:
#include <cmath>
const double imax = pow(2., 16.);
Но так как вы все равно имеете дело с константами, вам лучше:
const double imax = 65536.;
Если вы хотите сохранить выразительную силу 2**16
и вы не хотите нести стоимость звонка во время выполнения pow
(возможно, вы хотите изменить показатель степени без необходимости вручную пересчитывать константу), вы можете использовать constexpr
функция:
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);
Вот объяснение всех нетривиальных линий, которые вы обрисовали в общих чертах:
len(t)
средства «длина t
«, то есть количество элементов в массиве t.
2**16
является «двое к власти 16» (1 << 16
в вашем коде C ++).
for n in range(0,L)
эквивалентно for (int n = 0; i < L; ++i)
arange
а также zeros
скорее всего функции Numpy. Вы можете найти ссылку на них Вот а также Вот.
Что касается последнего пункта, вероятно, есть некоторые import
заявление вы пропустили из кода.
Цитирование из документов:
Вернуть равномерно распределенные значения в заданном интервале.
Значения генерируются в пределах полуоткрытого интервала [начало, остановка) (другими словами, интервал, включающий начало, но исключая остановку).
Шаг по умолчанию 1
, так t
будет массив, содержащий числа [0, 1, 2, 3, ..., 3 * 44100 - 1]
,
Вернуть новый массив заданной формы и типа, заполненный нулями.
Тип по умолчанию для zeros
является float
, так s
, sd1
а также sd2
инициализируются как массивы, заполненные 0.0
каждый из которых имеет L
элементы.
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++)