//decimate sound to SAMPLE_RATE, using averaging void decimate(const u::bytes& s, u::bytes& d, size_t channels, size_t skip) { REQUIRE_FALSE(s.empty()); REQUIRE_EQUAL(s.size() % 2, 0); //get sizes auto dz = (s.size() / skip); auto nz = d.size() + dz; //add padding if(nz % 2 == 1) nz += 1; CHECK_EQUAL(nz % 2, 0); //resize dest const auto odz = d.size(); d.resize(nz); //cast to short arrays auto ss = reinterpret_cast<const short*>(s.data()); const auto sz = s.size() / 2; auto sd = reinterpret_cast<short*>(d.data()); const auto sdz = nz / 2; int accum = 0; size_t c = 1; size_t si = 0; auto di = odz / 2; for(;si < sz; si+=channels) { accum += static_cast<int>(ss[si]); if(c == skip) { accum /= c; sd[di] = accum; di++; accum = 0; c = 1; continue; } c++; } //repeat last value if we have padding si = sz-1; while(di < sdz) { sd[di] = ss[si]; di++; } CHECK_EQUAL(di, sdz); }
void inflate(const u::bytes& s, u::bytes& d, size_t channels, size_t rep) { REQUIRE_EQUAL(s.size() % 2, 0); rep*=channels; d.resize(s.size() * rep); auto ss = reinterpret_cast<const short*>(s.data()); auto sz = s.size() / 2; auto sd = reinterpret_cast<short*>(d.data()); size_t di = 0; for(size_t si = 0; si < sz; si++) for(size_t p = 0; p < rep; p++, di++) sd[di] = ss[si]; }
//simple low pass filter void reduce_noise(u::bytes& s, size_t len) { REQUIRE_EQUAL(s.size() % 2, 0); auto ss = reinterpret_cast<short*>(s.data()); len /= 2; for(size_t i = 1; i < len; i++) ss[i] = (0.333 * ss[i]) + ((1 - 0.333) * ss[i-1]) + 0.5; }
u::bytes public_key::encrypt(const u::bytes& b) const { INVARIANT(_k); INVARIANT_FALSE(_ks.empty()); u::mutex_scoped_lock l(BOTAN_MUTEX); init_rng(); CHECK(RNG); std::stringstream rs; b::PK_Encryptor_EME e{*_k, EME_SCHEME}; size_t advance = 0; while(advance < b.size()) { size_t size = std::min(e.maximum_input_size(), b.size()-advance); auto c = e.encrypt(reinterpret_cast<const unsigned char*>(b.data())+advance, size, *RNG); u::bytes bs{std::begin(c), std::end(c)}; rs << bs; advance+=size; } return u::to_bytes(rs.str()); }
u::bytes private_key::sign(const u::bytes& b) const { INVARIANT(_k); u::mutex_scoped_lock l(BOTAN_MUTEX); init_rng(); CHECK(RNG); b::PK_Signer s{*_k, EMSA_SCHEME}; auto r = s.sign_message(reinterpret_cast<const unsigned char*>(b.data()), b.size(), *RNG); ENSURE_EQUAL(r.size(), SIGNATURE_SIZE); return u::bytes {std::begin(r), std::end(r)}; }