//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]; }