blob: ddb920dd6d4973e0b11c93210ef0b96a3c96495b [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <vector>
#include "src/media/audio/lib/format2/fixed.h"
#include "src/media/audio/lib/processing/coefficient_table.h"
namespace {
using ::media_audio::CoefficientTable;
using ::media_audio::Fixed;
using ::media_audio::SincFilterCoefficientTable;
struct Key {
int32_t source_rate;
int32_t dest_rate;
SincFilterCoefficientTable::Inputs MakeInputs() {
return SincFilterCoefficientTable::MakeInputs(source_rate, dest_rate);
}
};
} // namespace
int main(int argc, const char** argv) {
if (argc != 2) {
std::cerr << "Usage: [program] [output_filename]\n";
return 1;
}
std::ofstream out(argv[1]);
out << "// Copyright 2021 The Fuchsia Authors. All rights reserved.\n";
out << "// Use of this source code is governed by a BSD-style license that can be\n";
out << "// found in the LICENSE file.\n";
out << "//\n";
out << "// Generated by gen_coefficient_tables.cc.\n";
out << "\n";
out << "#include \"src/media/audio/lib/processing/coefficient_table.h\"\n";
out << "\n";
out << "namespace media_audio {\n";
out << "\n";
out << "// Static asserts to validate that the generated code is not out-of-date\n";
out << "static_assert(media_audio::kPtsFractionalBits == " << Fixed::Format::FractionalBits
<< ");\n";
out << "static_assert(media_audio::SincFilterCoefficientTable::kSideTaps == "
<< SincFilterCoefficientTable::kSideTaps << ");\n";
out << "static_assert(media_audio::SincFilterCoefficientTable::kFracSideLength == "
<< SincFilterCoefficientTable::kFracSideLength << ");\n";
out << "\n";
// TODO(fxbug.dev/86662): Move these to a shared header, to eliminate duplication with filter.cc.
std::vector<Key> keys = {
// clang-format off
{48000, 48000},
{96000, 48000},
{48000, 96000},
{96000, 16000},
{48000, 16000},
{44100, 48000},
{16000, 48000},
// clang-format on
};
std::vector<std::unique_ptr<CoefficientTable>> tables;
for (auto key : keys) {
tables.push_back(SincFilterCoefficientTable::Create(key.MakeInputs()));
}
// Print each table as an individual C array.
for (size_t k = 0; k < tables.size(); k++) {
out << "static const float kPrebuiltTableData" << k << "[] = {\n ";
size_t count = 0;
for (auto x : tables[k]->raw_table()) {
out << std::scientific << std::setprecision(std::numeric_limits<decltype(x)>::max_digits10)
<< x << "f, ";
count++;
if (count == tables[k]->raw_table().size()) {
out << "\n";
} else if (count % (SincFilterCoefficientTable::kSideTaps + 1) == 0) {
out << "\n ";
}
}
out << "};\n";
out << "\n";
}
// Print the collection of tables as an array of structs.
out << "static const PrebuiltSincFilterCoefficientTable kPrebuiltTables[] = {\n";
for (size_t k = 0; k < tables.size(); k++) {
out << " {\n";
out << " .source_rate = " << keys[k].source_rate << ",\n";
out << " .dest_rate = " << keys[k].dest_rate << ",\n";
out << " .table = cpp20::span<const float>(kPrebuiltTableData" << k
<< ", static_cast<size_t>(" << tables[k]->raw_table().size() << ")),\n";
out << " },\n";
}
out << "};\n";
out << "\n";
// Now translate to a span.
out << "const cpp20::span<const PrebuiltSincFilterCoefficientTable> "
"kPrebuiltSincFilterCoefficientTables(kPrebuiltTables, static_cast<size_t>("
<< tables.size() << "));\n";
out << "\n";
out << "} // namespace media_audio\n";
return 0;
}