diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e5534fd --- /dev/null +++ b/.clang-format @@ -0,0 +1,39 @@ +# Language +Language: Cpp + +# Style +BasedOnStyle: Microsoft + +# No indent for extern block and namespace +IndentExternBlock: NoIndent +NamespaceIndentation: None + +# Header files order +IncludeIsMainRegex: ".*" # 1. main file +IncludeCategories: + - Regex: '^' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*>' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 + +# Indentation +IndentWidth: 4 + +# Line length +ColumnLimit: 100 + +# Break before braces +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: true + AfterControlStatement: true + AfterFunction: true + AfterNamespace: true + + +KeepEmptyLinesAtTheStartOfBlocks: false diff --git a/.github/workflows/native-build.yaml b/.github/workflows/native-build.yaml index 4be52c5..da5a1a4 100644 --- a/.github/workflows/native-build.yaml +++ b/.github/workflows/native-build.yaml @@ -25,7 +25,10 @@ jobs: submodules: recursive - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y cmake build-essential libfftw3-dev libcurl4-openssl-dev ffmpeg jq yt-dlp + run: sudo apt-get update && sudo apt-get install -y cmake build-essential libfftw3-dev libcurl4-openssl-dev ffmpeg cpplint + + - name: Check cpplint + run: cpplint --recursive lib include - name: Configure CMake run: cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} @@ -37,4 +40,4 @@ jobs: run: sudo make install -C build - name: Test CLI - run: vibra --recognize --file tests/sample.mp3 | jq .track.title -r | grep -q "Misty" \ No newline at end of file + run: cd tests && ./test.sh 5 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a21be5..ac7ae47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -pedantic -O2 -fno-strict-aliasing") +include_directories(${CMAKE_SOURCE_DIR}/lib) # build verbose output # set(CMAKE_VERBOSE_MAKEFILE ON) diff --git a/CPPLINT.cfg b/CPPLINT.cfg new file mode 100644 index 0000000..12e1ad9 --- /dev/null +++ b/CPPLINT.cfg @@ -0,0 +1,4 @@ +set noparent +linelength=100 +filter=-whitespace/newline,-whitespace/braces,-whitespace/parens,-whitespace/indent,-whitespace/comments,-legal/copyright +exclude_files=./cli/args \ No newline at end of file diff --git a/cli/cli.cpp b/cli/cli.cpp index 8fe351a..d345bf4 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -1,20 +1,20 @@ -#include -#include +#include "../cli/cli.h" #include -#include "cli.h" +#include +#include +#include #include "args/args.hxx" -static std::string read_buffer; +static std::string read_buffer; // NOLINT -std::size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) +std::size_t writeCallback(void *contents, size_t size, size_t nmemb, void *) { - (void)userp; // suppress warning (unused parameter) std::size_t realsize = size * nmemb; - read_buffer.append((char*)contents, realsize); + read_buffer.append(reinterpret_cast(contents), realsize); return realsize; } -int CLI::Run(int argc, char** argv) +int CLI::Run(int argc, char **argv) { args::ArgumentParser parser(""); parser.SetArgumentSeparations(false, false, true, true); @@ -28,23 +28,25 @@ int CLI::Run(int argc, char** argv) parser.helpParams.showValueName = false; parser.helpParams.optionsString = "Options:"; parser.helpParams.proglineOptions = "{COMMAND} [OPTIONS]"; - + args::Group actions(parser, "Commands:", args::Group::Validators::Xor); - args::Flag fingerprint_only(actions, "fingerprint", "Generate a fingerprint", {'F', "fingerprint"}); + args::Flag fingerprint_only(actions, "fingerprint", "Generate a fingerprint", + {'F', "fingerprint"}); args::Flag recognize(actions, "recognize", "Recognize a song", {'R', "recognize"}); args::HelpFlag help(actions, "help", "Display this help menu", {'h', "help"}); - + args::Group sources(parser, "Sources:", args::Group::Validators::Xor); args::Group file_sources(sources, "File sources:", args::Group::Validators::Xor); - args::ValueFlag music_file(file_sources, "file", "FFmpeg required for non-wav files", {'f', "file"}); - + args::ValueFlag music_file(file_sources, "file", + "FFmpeg required for non-wav files", {'f', "file"}); + args::Group raw_sources(sources, "Raw PCM sources:", args::Group::Validators::All); args::ValueFlag chunk_seconds(raw_sources, "seconds", "Chunk seconds", {'s', "seconds"}); args::ValueFlag sample_rate(raw_sources, "rate", "Sample rate", {'r', "rate"}); args::ValueFlag channels(raw_sources, "channels", "Channels", {'c', "channels"}); args::ValueFlag bits_per_sample(raw_sources, "bits", "Bits per sample", {'b', "bits"}); - + args::Group source_type(raw_sources, "Source type:", args::Group::Validators::AtMostOne); args::Flag signed_pcm(source_type, "signed", "Signed PCM (default)", {'S', "signed"}); args::Flag float_pcm(source_type, "float", "Float PCM", {'D', "float"}); @@ -53,12 +55,12 @@ int CLI::Run(int argc, char** argv) { parser.ParseCLI(argc, argv); } - catch (const args::Help&) + catch (const args::Help &) { std::cout << parser; return 0; } - catch (const std::runtime_error& e) + catch (const std::runtime_error &e) { std::cerr << std::endl; std::cerr << e.what() << std::endl; @@ -67,7 +69,7 @@ int CLI::Run(int argc, char** argv) return 1; } - Fingerprint* fingerprint = nullptr; + Fingerprint *fingerprint = nullptr; if (music_file) { std::string file = args::get(music_file); @@ -76,20 +78,16 @@ int CLI::Run(int argc, char** argv) else if (chunk_seconds && sample_rate && channels && bits_per_sample) { bool is_signed = signed_pcm || !float_pcm; - fingerprint = getFingerprintFromStdin( - args::get(chunk_seconds), - args::get(sample_rate), - args::get(channels), - args::get(bits_per_sample), - is_signed - ); + fingerprint = + getFingerprintFromStdin(args::get(chunk_seconds), args::get(sample_rate), + args::get(channels), args::get(bits_per_sample), is_signed); } else { std::cerr << "Invalid arguments" << std::endl; - return 1; + return 1; } - + if (fingerprint_only) { std::cout << fingerprint->uri << std::endl; @@ -101,7 +99,7 @@ int CLI::Run(int argc, char** argv) return 0; } -Fingerprint* CLI::getFingerprintFromMusicFile(const std::string& music_file) +Fingerprint *CLI::getFingerprintFromMusicFile(const std::string &music_file) { if (std::ifstream(music_file).good() == false) { @@ -111,31 +109,33 @@ Fingerprint* CLI::getFingerprintFromMusicFile(const std::string& music_file) return vibra_get_fingerprint_from_music_file(music_file.c_str()); } -Fingerprint* CLI::getFingerprintFromStdin(int chunk_seconds, int sample_rate, - int channels, int bits_per_sample, bool is_signed) +Fingerprint *CLI::getFingerprintFromStdin(int chunk_seconds, int sample_rate, int channels, + int bits_per_sample, bool is_signed) { std::size_t bytes = chunk_seconds * sample_rate * channels * (bits_per_sample / 8); std::vector buffer(bytes); std::cin.read(buffer.data(), bytes); if (is_signed) { - return vibra_get_fingerprint_from_signed_pcm(buffer.data(), bytes, sample_rate, bits_per_sample, channels); + return vibra_get_fingerprint_from_signed_pcm(buffer.data(), bytes, sample_rate, + bits_per_sample, channels); } - return vibra_get_fingerprint_from_float_pcm(buffer.data(), bytes, sample_rate, bits_per_sample, channels); + return vibra_get_fingerprint_from_float_pcm(buffer.data(), bytes, sample_rate, bits_per_sample, + channels); } -std::string CLI::getMetadataFromShazam(const Fingerprint* fingerprint) +std::string CLI::getMetadataFromShazam(const Fingerprint *fingerprint) { auto content = vibra_get_shazam_request_json(fingerprint); auto user_agent = vibra_get_shazam_random_user_agent(); std::string url = vibra_get_shazam_host(); - CURL* curl = curl_easy_init(); + CURL *curl = curl_easy_init(); read_buffer.clear(); - if (curl) + if (curl) { - struct curl_slist* headers = nullptr; + struct curl_slist *headers = nullptr; headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate, br"); headers = curl_slist_append(headers, "Accept: */*"); headers = curl_slist_append(headers, "Connection: keep-alive"); @@ -148,19 +148,26 @@ std::string CLI::getMetadataFromShazam(const Fingerprint* fingerprint) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &read_buffer); - + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br"); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); - + CURLcode res = curl_easy_perform(curl); - if (res != CURLE_OK) + if (res != CURLE_OK) { std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; } - long http_code = 0; + long http_code = 0; // NOLINT + /* + Jayden: + + I don't know why, if type of http_code is std::int32_t, + it will cause a double free corrupt error. + */ + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if (http_code != 200) + if (http_code != 200) { std::cerr << "HTTP code: " << http_code << std::endl; } @@ -168,4 +175,4 @@ std::string CLI::getMetadataFromShazam(const Fingerprint* fingerprint) curl_easy_cleanup(curl); } return read_buffer; -} \ No newline at end of file +} diff --git a/cli/cli.h b/cli/cli.h index f58a778..b200e96 100644 --- a/cli/cli.h +++ b/cli/cli.h @@ -1,20 +1,19 @@ -#ifndef __CLI_H__ -#define __CLI_H__ +#ifndef CLI_CLI_H_ +#define CLI_CLI_H_ #include #include "../include/vibra.h" -class CLI +class CLI { -public: - int Run(int argc, char** argv); - -private: - Fingerprint* getFingerprintFromMusicFile(const std::string& music_file); - Fingerprint* getFingerprintFromStdin(int chunk_seconds, int sample_rate, - int channels, int bits_per_sample, bool is_signed); - std::string getMetadataFromShazam(const Fingerprint* fingerprint); + public: + int Run(int argc, char **argv); + private: + Fingerprint *getFingerprintFromMusicFile(const std::string &music_file); + Fingerprint *getFingerprintFromStdin(int chunk_seconds, int sample_rate, int channels, + int bits_per_sample, bool is_signed); + std::string getMetadataFromShazam(const Fingerprint *fingerprint); }; -#endif // __CLI_H__ +#endif // CLI_CLI_H_ diff --git a/cli/main.cpp b/cli/main.cpp index 80ed43e..f2d23f5 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -1,7 +1,7 @@ -#include "cli.h" +#include "./cli.h" -int main(int argc, char** argv) +int main(int argc, char **argv) { CLI cli; return cli.Run(argc, argv); -} \ No newline at end of file +} diff --git a/include/vibra.h b/include/vibra.h index 370adcc..a517b29 100644 --- a/include/vibra.h +++ b/include/vibra.h @@ -1,14 +1,14 @@ -#ifndef __VIBRA_H__ -#define __VIBRA_H__ +#ifndef INCLUDE_VIBRA_H_ +#define INCLUDE_VIBRA_H_ #include -extern "C" { - +extern "C" +{ /** * @brief Structure to hold a music fingerprint. - * - * @note The structure is thread-unsafe and does not require manual memory management + * + * @note The structure is thread-unsafe and does not require manual memory management * for the returned pointer. */ struct Fingerprint @@ -19,124 +19,104 @@ struct Fingerprint /** * @brief Generate a fingerprint from a music file. - * + * * @param music_file_path The path to the music file. * @return Fingerprint* Pointer to the generated fingerprint. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -Fingerprint* vibra_get_fingerprint_from_music_file( - const char* music_file_path -); +Fingerprint *vibra_get_fingerprint_from_music_file(const char *music_file_path); /** * @brief Generate a fingerprint from WAV data. - * + * * @param raw_wav The raw WAV data. * @param wav_data_size The size of the WAV data in bytes. * @return Fingerprint* Pointer to the generated fingerprint. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -Fingerprint* vibra_get_fingerprint_from_wav_data( - const char* raw_wav, - int wav_data_size -); +Fingerprint *vibra_get_fingerprint_from_wav_data(const char *raw_wav, int wav_data_size); /** * @brief Generate a fingerprint from signed PCM data. - * + * * @param raw_pcm The raw PCM data. * @param pcm_data_size The size of the PCM data in bytes. * @param sample_rate The sample rate of the PCM data. * @param sample_width The sample width (bits per sample) of the PCM data. * @param channel_count The number of channels in the PCM data. * @return Fingerprint* Pointer to the generated fingerprint. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -Fingerprint* vibra_get_fingerprint_from_signed_pcm( - const char* raw_pcm, - int pcm_data_size, - int sample_rate, - int sample_width, - int channel_count -); +Fingerprint *vibra_get_fingerprint_from_signed_pcm(const char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count); /** * @brief Generate a fingerprint from PCM data. - * + * * @param raw_pcm The raw PCM data. * @param pcm_data_size The size of the PCM data in bytes. * @param sample_rate The sample rate of the PCM data. * @param sample_width The sample width (bits per sample) of the PCM data. * @param channel_count The number of channels in the PCM data. * @return Fingerprint* Pointer to the generated fingerprint. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -Fingerprint* vibra_get_fingerprint_from_float_pcm( - const char* raw_pcm, - int pcm_data_size, - int sample_rate, - int sample_width, - int channel_count -); +Fingerprint *vibra_get_fingerprint_from_float_pcm(const char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count); /** * @brief Get the URI associated with a fingerprint. - * + * * @param fingerprint Pointer to the fingerprint. * @return const char* The URI as a C-string. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -const char* vibra_get_uri_from_fingerprint( - Fingerprint* fingerprint -); +const char *vibra_get_uri_from_fingerprint(Fingerprint *fingerprint); /** * @brief Get the sample duration in milliseconds from a fingerprint. - * + * * @param fingerprint Pointer to the fingerprint. * @return unsigned int The sample duration in milliseconds. - * + * * @note This function is thread-unsafe. */ -unsigned int vibra_get_sample_ms_from_fingerprint( - Fingerprint* fingerprint -); +unsigned int vibra_get_sample_ms_from_fingerprint(Fingerprint *fingerprint); /** * @brief Generate a Shazam request JSON from a fingerprint. - * + * * @param fingerprint Pointer to the fingerprint. * @return const char* The Shazam request JSON as a C-string. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -const char* vibra_get_shazam_request_json( - const Fingerprint* fingerprint -); +const char *vibra_get_shazam_request_json(const Fingerprint *fingerprint); /** * @brief Get the Shazam host URL. - * + * * @return const char* The Shazam host URL as a C-string. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -const char* vibra_get_shazam_host(); +const char *vibra_get_shazam_host(); /** * @brief Get a random Shazam user agent string. - * + * * @return const char* A random Shazam user agent as a C-string. - * + * * @note This function is thread-unsafe and the returned pointer should not be freed. */ -const char* vibra_get_shazam_random_user_agent(); - +const char *vibra_get_shazam_random_user_agent(); } // extern "C" -#endif // __VIBRA_H__ \ No newline at end of file +#endif // INCLUDE_VIBRA_H_ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index b5a4c01..da0a7b8 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -13,6 +13,9 @@ set(LIBVIBRA_SOURCES add_library(vibra_shared SHARED ${LIBVIBRA_SOURCES}) add_library(vibra_static STATIC ${LIBVIBRA_SOURCES}) +target_include_directories(vibra_shared PRIVATE ${CMAKE_SOURCE_DIR}/include) +target_include_directories(vibra_static PRIVATE ${CMAKE_SOURCE_DIR}/include) + if (DEFINED FFTW3_PATH) set(FFTW3_INCLUDE_DIR ${FFTW3_PATH}/include) set(FFTW3_LIBRARY ${FFTW3_PATH}/lib/libfftw3.a) diff --git a/lib/algorithm/frequency.cpp b/lib/algorithm/frequency.cpp index 3f4e5d5..ef50a82 100644 --- a/lib/algorithm/frequency.cpp +++ b/lib/algorithm/frequency.cpp @@ -1,11 +1,10 @@ -#include "frequency.h" +#include "algorithm/frequency.h" #include -FrequancyPeak::FrequancyPeak(std::uint32_t fft_pass_number, std::uint32_t peak_magnitude, std::uint32_t corrected_peak_frequency_bin, std::uint32_t sample_rate) - : mFFTPassNumber(fft_pass_number) - , mPeakMagnitude(peak_magnitude) - , mCorrectedPeakFrequencyBin(corrected_peak_frequency_bin) - , mSampleRate(sample_rate) +FrequancyPeak::FrequancyPeak(std::uint32_t fft_pass_number, std::uint32_t peak_magnitude, + std::uint32_t corrected_peak_frequency_bin, std::uint32_t sample_rate) + : fft_pass_number_(fft_pass_number), peak_magnitude_(peak_magnitude), + corrected_peak_frequency_bin_(corrected_peak_frequency_bin), sample_rate_(sample_rate) { } @@ -13,17 +12,17 @@ FrequancyPeak::~FrequancyPeak() { } -double FrequancyPeak::GetFrequencyHz() const +double FrequancyPeak::ComputeFrequency() const { - return mCorrectedPeakFrequencyBin * ((double)mSampleRate / 2. / 1024. / 64.); + return corrected_peak_frequency_bin_ * (static_cast(sample_rate_) / 2. / 1024. / 64.); } - -double FrequancyPeak::GetAmplitudePCM() const + +double FrequancyPeak::ComputeAmplitudePCM() const { - return std::sqrt(std::exp((mPeakMagnitude - 6144) / 1477.3) * (1 << 17) / 2.) / 1024.; + return std::sqrt(std::exp((peak_magnitude_ - 6144) / 1477.3) * (1 << 17) / 2.) / 1024.; } -double FrequancyPeak::GetSeconds() const +double FrequancyPeak::ComputeElapsedSeconds() const { - return (double)mFFTPassNumber * 128. / (double)mSampleRate; -} \ No newline at end of file + return static_cast(fft_pass_number_) * 128. / static_cast(sample_rate_); +} diff --git a/lib/algorithm/frequency.h b/lib/algorithm/frequency.h index e106e2a..7183102 100644 --- a/lib/algorithm/frequency.h +++ b/lib/algorithm/frequency.h @@ -1,5 +1,5 @@ -#ifndef FREQUENCY_H -#define FREQUENCY_H +#ifndef LIB_ALGORITHM_FREQUENCY_H_ +#define LIB_ALGORITHM_FREQUENCY_H_ #include @@ -14,22 +14,32 @@ enum class FrequancyBand class FrequancyPeak { -public: - FrequancyPeak(std::uint32_t fft_pass_number, std::uint32_t peak_magnitude, std::uint32_t corrected_peak_frequency_bin, std::uint32_t sample_rate); + public: + FrequancyPeak(std::uint32_t fft_pass_number, std::uint32_t peak_magnitude, + std::uint32_t corrected_peak_frequency_bin, std::uint32_t sample_rate); ~FrequancyPeak(); - inline std::uint32_t GetFFTPassNumber() const { return mFFTPassNumber; } - inline std::uint32_t GetPeakMagnitude() const { return mPeakMagnitude; } - inline std::uint32_t GetCorrectedPeakFrequencyBin() const { return mCorrectedPeakFrequencyBin; } - double GetFrequencyHz() const; - double GetAmplitudePCM() const; - double GetSeconds() const; + inline std::uint32_t fft_pass_number() const + { + return fft_pass_number_; + } + inline std::uint32_t peak_magnitude() const + { + return peak_magnitude_; + } + inline std::uint32_t corrected_peak_frequency_bin() const + { + return corrected_peak_frequency_bin_; + } + inline double ComputeFrequency() const; + inline double ComputeAmplitudePCM() const; + inline double ComputeElapsedSeconds() const; -private: - std::uint32_t mFFTPassNumber; - std::uint32_t mPeakMagnitude; - std::uint32_t mCorrectedPeakFrequencyBin; - std::uint32_t mSampleRate; + private: + std::uint32_t fft_pass_number_; + std::uint32_t peak_magnitude_; + std::uint32_t corrected_peak_frequency_bin_; + std::uint32_t sample_rate_; }; -#endif // FREQUENCY_H \ No newline at end of file +#endif // LIB_ALGORITHM_FREQUENCY_H_ diff --git a/lib/algorithm/signature.cpp b/lib/algorithm/signature.cpp index d8a9190..30e6caa 100644 --- a/lib/algorithm/signature.cpp +++ b/lib/algorithm/signature.cpp @@ -1,67 +1,68 @@ -#include "signature.h" -#include "../utils/crc32.h" -#include "../utils/base64.h" -#include +#include "algorithm/signature.h" #include +#include +#include +#include "utils/base64.h" +#include "utils/crc32.h" -Signature::Signature(std::uint32_t sampleRate, std::uint32_t numberOfSamples) - : mSampleRate(sampleRate) - , mNumberOfSamples(numberOfSamples) +Signature::Signature(std::uint32_t sample_rate, std::uint32_t num_samples) + : sample_rate_(sample_rate), num_samples_(num_samples) { } -void Signature::Reset(std::uint32_t sampleRate, std::uint32_t numberOfSamples) +void Signature::Reset(std::uint32_t sampleRate, std::uint32_t num_samples) { - mSampleRate = sampleRate; - mNumberOfSamples = numberOfSamples; - mFrequancyBandToPeaks.clear(); + sample_rate_ = sampleRate; + num_samples_ = num_samples; + frequancy_band_to_peaks_.clear(); } std::uint32_t Signature::SumOfPeaksLength() const { std::uint32_t sum = 0; - for (const auto& pair : mFrequancyBandToPeaks) + for (const auto &pair : frequancy_band_to_peaks_) { sum += pair.second.size(); } return sum; } -std::string Signature::GetBase64Uri() const +std::string Signature::EncodeBase64() const { RawSignatureHeader header; header.magic1 = 0xcafe2580; header.magic2 = 0x94119c00; header.shifted_sample_rate_id = 3 << 27; header.fixed_value = ((15 << 19) + 0x40000); - header.number_samples_plus_divided_sample_rate = static_cast(mNumberOfSamples + mSampleRate * 0.24); + header.number_samples_plus_divided_sample_rate = + static_cast(num_samples_ + sample_rate_ * 0.24); std::stringstream contents; - for (const auto& pair : mFrequancyBandToPeaks) + for (const auto &pair : frequancy_band_to_peaks_) { - const auto& band = pair.first; - const auto& peaks = pair.second; + const auto &band = pair.first; + const auto &peaks = pair.second; std::stringstream peak_buf; std::size_t fft_pass_number = 0; - for (const auto& peak : peaks) - { - if (peak.GetFFTPassNumber() - fft_pass_number >= 255) + for (const auto &peak : peaks) + { + if (peak.fft_pass_number() - fft_pass_number >= 255) { peak_buf << "\xff"; - writeLittleEndian(peak_buf, peak.GetFFTPassNumber()); - fft_pass_number = peak.GetFFTPassNumber(); + write_little_endian(peak_buf, peak.fft_pass_number()); + fft_pass_number = peak.fft_pass_number(); } - peak_buf << static_cast(peak.GetFFTPassNumber() - fft_pass_number); - writeLittleEndian(peak_buf, peak.GetPeakMagnitude(), 2); - writeLittleEndian(peak_buf, peak.GetCorrectedPeakFrequencyBin(), 2); + peak_buf << static_cast(peak.fft_pass_number() - fft_pass_number); + write_little_endian(peak_buf, peak.peak_magnitude(), 2); + write_little_endian(peak_buf, peak.corrected_peak_frequency_bin(), 2); - fft_pass_number = peak.GetFFTPassNumber(); + fft_pass_number = peak.fft_pass_number(); } - writeLittleEndian(contents, 0x60030040u + static_cast(band)); - writeLittleEndian(contents, static_cast(peak_buf.str().size())); + write_little_endian(contents, 0x60030040u + static_cast(band)); + write_little_endian(contents, static_cast(peak_buf.str().size())); contents << peak_buf.str(); for (std::size_t i = 0; i < (-peak_buf.str().size() % 4); ++i) @@ -69,29 +70,29 @@ std::string Signature::GetBase64Uri() const } header.size_minus_header = contents.str().size() + 8; - + std::stringstream header_buf; - header_buf.write(reinterpret_cast(&header), sizeof(header)); + header_buf.write(reinterpret_cast(&header), sizeof(header)); - writeLittleEndian(header_buf, 0x40000000u); - writeLittleEndian(header_buf, static_cast(contents.str().size()) + 8); + write_little_endian(header_buf, 0x40000000u); + write_little_endian(header_buf, static_cast(contents.str().size()) + 8); header_buf << contents.str(); - const auto& header_buf_str = header_buf.str(); + const auto &header_buf_str = header_buf.str(); header.crc32 = crc32::crc32(header_buf_str.c_str() + 8, header_buf_str.size() - 8) & 0xffffffff; header_buf.seekp(0); - header_buf.write(reinterpret_cast(&header), sizeof(header)); + header_buf.write(reinterpret_cast(&header), sizeof(header)); std::string header_string = header_buf.str(); - - std::string base64Uri; - base64Uri += "data:audio/vnd.shazam.sig;base64,"; - base64Uri += base64::encode(header_string.c_str(), header_string.size()); - return base64Uri; + + std::string base64_uri; + base64_uri += "data:audio/vnd.shazam.sig;base64,"; + base64_uri += base64::encode(header_string.c_str(), header_string.size()); + return base64_uri; } Signature::~Signature() { -} \ No newline at end of file +} diff --git a/lib/algorithm/signature.h b/lib/algorithm/signature.h index 79f56ec..fa71b71 100644 --- a/lib/algorithm/signature.h +++ b/lib/algorithm/signature.h @@ -1,17 +1,19 @@ -#ifndef SIGNATURE_H -#define SIGNATURE_H +#ifndef LIB_ALGORITHM_SIGNATURE_H_ +#define LIB_ALGORITHM_SIGNATURE_H_ -#include #include +#include #include #include -#include "frequency.h" +#include +#include "algorithm/frequency.h" // Prevent Structure Padding #ifdef _MSC_VER - #pragma pack(push, 1) +#pragma pack(push, 1) #endif -struct RawSignatureHeader { +struct RawSignatureHeader +{ uint32_t magic1; uint32_t crc32; uint32_t size_minus_header; @@ -21,30 +23,43 @@ struct RawSignatureHeader { uint32_t void2[2]; uint32_t number_samples_plus_divided_sample_rate; uint32_t fixed_value; -} +} #ifdef _MSC_VER - #pragma pack(pop) +#pragma pack(pop) #else - __attribute__((packed)); +__attribute__((packed)); #endif class Signature { -public: - Signature(std::uint32_t sampleRate, std::uint32_t numberOfSamples); + public: + Signature(std::uint32_t sample_rate, std::uint32_t num_samples); ~Signature(); - void Reset(std::uint32_t sampleRate, std::uint32_t numberOfSamples); + void Reset(std::uint32_t sampleRate, std::uint32_t num_samples); - inline void AddNumberOfSamples(std::uint32_t numberOfSamples) { mNumberOfSamples += numberOfSamples; } - inline std::uint32_t SampleRate() const { return mSampleRate; } - inline std::uint32_t NumberOfSamples() const { return mNumberOfSamples; } - inline std::map>& FrequancyBandToPeaks() { return mFrequancyBandToPeaks; } + inline void Addnum_samples(std::uint32_t num_samples) + { + num_samples_ += num_samples; + } + inline std::uint32_t sample_rate() const + { + return sample_rate_; + } + inline std::uint32_t num_samples() const + { + return num_samples_; + } + inline std::map> &frequancy_band_to_peaks() + { + return frequancy_band_to_peaks_; + } std::uint32_t SumOfPeaksLength() const; - std::string GetBase64Uri() const; + std::string EncodeBase64() const; -private: + private: template - std::stringstream& writeLittleEndian(std::stringstream& stream, const T&& value, size_t size = sizeof(T)) const + std::stringstream &write_little_endian(std::stringstream &stream, const T &&value, + size_t size = sizeof(T)) const { for (size_t i = 0; i < size; ++i) { @@ -53,11 +68,10 @@ class Signature return stream; } -private: - std::uint32_t mSampleRate; - std::uint32_t mNumberOfSamples; - std::map> mFrequancyBandToPeaks; + private: + std::uint32_t sample_rate_; + std::uint32_t num_samples_; + std::map> frequancy_band_to_peaks_; }; -#endif // SIGNATURE_Hs - +#endif // LIB_ALGORITHM_SIGNATURE_H_ diff --git a/lib/algorithm/signature_generator.cpp b/lib/algorithm/signature_generator.cpp index 84f1e02..b93361e 100644 --- a/lib/algorithm/signature_generator.cpp +++ b/lib/algorithm/signature_generator.cpp @@ -1,53 +1,53 @@ -#include "signature_generator.h" -#include "../utils/hanning.h" +#include "algorithm/signature_generator.h" #include -#include #include +#include +#include +#include +#include "utils/hanning.h" SignatureGenerator::SignatureGenerator() - : mInputPendingProcessing() - , mSampleProcessed(0) - , mMaxTimeSeconds(3.1) - , mNextSignature(16000, 0) - , mRingBufferOfSamples(2048, 0) - , mFFTOutputs(256, fft::RealArray(1025, 0.0)) - , mSpreadFFTsOutput(256, fft::RealArray(1025, 0.0)) + : input_pending_processing_(), sample_processed_(0), max_time_seconds_(3.1), + next_signature_(16000, 0), samples_ring_buffer_(2048, 0), + fft_outputs_(256, fft::RealArray(1025, 0.0)), + spread_ffts_output_(256, fft::RealArray(1025, 0.0)) { } -void SignatureGenerator::FeedInput(const LowQualityTrack& input) +void SignatureGenerator::FeedInput(const LowQualityTrack &input) { - mInputPendingProcessing.reserve(mInputPendingProcessing.size() + input.size()); - mInputPendingProcessing.insert(mInputPendingProcessing.end(), input.begin(), input.end()); + input_pending_processing_.reserve(input_pending_processing_.size() + input.size()); + input_pending_processing_.insert(input_pending_processing_.end(), input.begin(), input.end()); } Signature SignatureGenerator::GetNextSignature() { - if (mInputPendingProcessing.size() - mSampleProcessed < 128) + if (input_pending_processing_.size() - sample_processed_ < 128) { throw std::runtime_error("Not enough input to generate signature"); } - while (mInputPendingProcessing.size() - mSampleProcessed >= 128 && - ((double)mNextSignature.NumberOfSamples() / mNextSignature.SampleRate() < mMaxTimeSeconds || - mNextSignature.SumOfPeaksLength() < MAX_PEAKS)) + double num_samples = static_cast(next_signature_.num_samples()); + while (input_pending_processing_.size() - sample_processed_ >= 128 && + (num_samples / next_signature_.sample_rate() < max_time_seconds_ || + next_signature_.SumOfPeaksLength() < MAX_PEAKS)) { - LowQualityTrack input(mInputPendingProcessing.begin() + mSampleProcessed, - mInputPendingProcessing.begin() + mSampleProcessed + 128); - - processInput(input); - mSampleProcessed += 128; + LowQualityTrack input(input_pending_processing_.begin() + sample_processed_, + input_pending_processing_.begin() + sample_processed_ + 128); + processInput(input); + sample_processed_ += 128; + num_samples = static_cast(next_signature_.num_samples()); } - Signature result = std::move(mNextSignature); + Signature result = std::move(next_signature_); resetSignatureGenerater(); return result; // RVO } -void SignatureGenerator::processInput(const LowQualityTrack& input) +void SignatureGenerator::processInput(const LowQualityTrack &input) { - mNextSignature.AddNumberOfSamples(input.size()); + next_signature_.Addnum_samples(input.size()); for (std::size_t chunk = 0; chunk < input.size(); chunk += 128) { LowQualityTrack chunk_input(input.begin() + chunk, input.begin() + chunk + 128); @@ -57,22 +57,23 @@ void SignatureGenerator::processInput(const LowQualityTrack& input) } } -void SignatureGenerator::doFFT(const LowQualityTrack& input) +void SignatureGenerator::doFFT(const LowQualityTrack &input) { std::copy(input.begin(), input.end(), - mRingBufferOfSamples.begin() + mRingBufferOfSamples.Position()); + samples_ring_buffer_.begin() + samples_ring_buffer_.position()); - mRingBufferOfSamples.Position() += input.size(); - mRingBufferOfSamples.Position() %= 2048; - mRingBufferOfSamples.NumWritten() += input.size(); + samples_ring_buffer_.position() += input.size(); + samples_ring_buffer_.position() %= 2048; + samples_ring_buffer_.num_written() += input.size(); fft::RealArray excerpt_from_ring_buffer(2048, 0.0); - std::copy(mRingBufferOfSamples.begin() + mRingBufferOfSamples.Position(), mRingBufferOfSamples.end(), - excerpt_from_ring_buffer.begin()); + std::copy(samples_ring_buffer_.begin() + samples_ring_buffer_.position(), + samples_ring_buffer_.end(), excerpt_from_ring_buffer.begin()); - std::copy(mRingBufferOfSamples.begin(), mRingBufferOfSamples.begin() + mRingBufferOfSamples.Position(), - excerpt_from_ring_buffer.begin() + 2048 - mRingBufferOfSamples.Position()); + std::copy(samples_ring_buffer_.begin(), + samples_ring_buffer_.begin() + samples_ring_buffer_.position(), + excerpt_from_ring_buffer.begin() + 2048 - samples_ring_buffer_.position()); for (int i = 0; i < 2048; ++i) { @@ -80,14 +81,14 @@ void SignatureGenerator::doFFT(const LowQualityTrack& input) } fft::RealArray real = fft::FFT::RFFT(excerpt_from_ring_buffer); - mFFTOutputs.Append(real); + fft_outputs_.Append(real); } void SignatureGenerator::doPeakSpreadingAndRecoginzation() { doPeakSpreading(); - if (mSpreadFFTsOutput.NumWritten() >= 47) + if (spread_ffts_output_.num_written() >= 47) { doPeakRecognition(); } @@ -95,31 +96,36 @@ void SignatureGenerator::doPeakSpreadingAndRecoginzation() void SignatureGenerator::doPeakSpreading() { - auto spread_last_fft = mFFTOutputs[mFFTOutputs.Position() - 1]; - + auto spread_last_fft = fft_outputs_[fft_outputs_.position() - 1]; + for (auto position = 0u; position < 1025; ++position) { if (position < 1023) { spread_last_fft[position] = *std::max_element(spread_last_fft.begin() + position, - spread_last_fft.begin() + position + 3); + spread_last_fft.begin() + position + 3); } - + auto max_value = spread_last_fft[position]; for (auto former_fft_num : {-1, -3, -6}) { - auto& former_fft_ouput = mSpreadFFTsOutput[(mSpreadFFTsOutput.Position() + former_fft_num) % mSpreadFFTsOutput.Size()]; - former_fft_ouput[position] = max_value = std::max(max_value, former_fft_ouput[position]); + auto &former_fft_ouput = + spread_ffts_output_[(spread_ffts_output_.position() + former_fft_num) % + spread_ffts_output_.size()]; + former_fft_ouput[position] = max_value = + std::max(max_value, former_fft_ouput[position]); } } - mSpreadFFTsOutput.Append(spread_last_fft); + spread_ffts_output_.Append(spread_last_fft); } void SignatureGenerator::doPeakRecognition() { - const auto& fft_minus_46 = mFFTOutputs[(mFFTOutputs.Position() - 46) % mFFTOutputs.Size()]; - const auto& fft_minus_49 = mSpreadFFTsOutput[(mSpreadFFTsOutput.Position() - 49) % mSpreadFFTsOutput.Size()]; + const auto &fft_minus_46 = fft_outputs_[(fft_outputs_.position() - 46) % fft_outputs_.size()]; + const auto &fft_minus_49 = + spread_ffts_output_[(spread_ffts_output_.position() - 49) % spread_ffts_output_.size()]; + auto other_offsets = {-53, -45, 165, 172, 179, 186, 193, 200, 214, 221, 228, 235, 242, 249}; for (auto bin_position = 10u; bin_position < 1025; ++bin_position) { if (fft_minus_46[bin_position] >= 1.0 / 64.0 && @@ -128,32 +134,41 @@ void SignatureGenerator::doPeakRecognition() auto max_neighbor_in_fft_minus_49 = 0.0l; for (auto neighbor_offset : {-10, -7, -4, -3, 1, 2, 5, 8}) { - max_neighbor_in_fft_minus_49 = std::max(max_neighbor_in_fft_minus_49, - fft_minus_49[bin_position + neighbor_offset]); + max_neighbor_in_fft_minus_49 = std::max( + max_neighbor_in_fft_minus_49, fft_minus_49[bin_position + neighbor_offset]); } if (fft_minus_46[bin_position] > max_neighbor_in_fft_minus_49) { auto max_neighbor_in_other_adjacent_ffts = max_neighbor_in_fft_minus_49; - for (auto other_offset : {-53, -45, 165, 172, 179, 186, 193, 200, 214, 221, 228, 235, 242, 249}) + for (auto other_offset : other_offsets) { max_neighbor_in_other_adjacent_ffts = std::max( max_neighbor_in_other_adjacent_ffts, - mSpreadFFTsOutput[(mSpreadFFTsOutput.Position() + other_offset) % mSpreadFFTsOutput.Size()][bin_position -1]); + spread_ffts_output_[(spread_ffts_output_.position() + other_offset) % + spread_ffts_output_.size()][bin_position - 1]); } if (fft_minus_46[bin_position] > max_neighbor_in_other_adjacent_ffts) { - auto fft_number = mSpreadFFTsOutput.NumWritten() - 46; - auto peak_magnitude = std::log(std::max(1.0l / 64, fft_minus_46[bin_position])) * 1477.3 + 6144; - auto peak_magnitude_before = std::log(std::max(1.0l / 64, fft_minus_46[bin_position - 1])) * 1477.3 + 6144; - auto peak_magnitude_after = std::log(std::max(1.0l / 64, fft_minus_46[bin_position + 1])) * 1477.3 + 6144; - - auto peak_variation_1 = peak_magnitude * 2 - peak_magnitude_before - peak_magnitude_after; - auto peak_variation_2 = (peak_magnitude_after - peak_magnitude_before) * 32 / peak_variation_1; + auto fft_number = spread_ffts_output_.num_written() - 46; + auto peak_magnitude = + std::log(std::max(1.0l / 64, fft_minus_46[bin_position])) * 1477.3 + 6144; + auto peak_magnitude_before = + std::log(std::max(1.0l / 64, fft_minus_46[bin_position - 1])) * 1477.3 + + 6144; + auto peak_magnitude_after = + std::log(std::max(1.0l / 64, fft_minus_46[bin_position + 1])) * 1477.3 + + 6144; + + auto peak_variation_1 = + peak_magnitude * 2 - peak_magnitude_before - peak_magnitude_after; + auto peak_variation_2 = + (peak_magnitude_after - peak_magnitude_before) * 32 / peak_variation_1; auto corrected_peak_frequency_bin = bin_position * 64.0 + peak_variation_2; - auto frequency_hz = corrected_peak_frequency_bin * (16000.0l / 2. / 1024. / 64.); + auto frequency_hz = + corrected_peak_frequency_bin * (16000.0l / 2. / 1024. / 64.); auto band = FrequancyBand(); if (frequency_hz < 250) @@ -169,15 +184,16 @@ void SignatureGenerator::doPeakRecognition() else continue; - auto& band_to_sound_peaks = mNextSignature.FrequancyBandToPeaks(); + auto &band_to_sound_peaks = next_signature_.frequancy_band_to_peaks(); if (band_to_sound_peaks.find(band) == band_to_sound_peaks.end()) { band_to_sound_peaks[band] = std::list(); } band_to_sound_peaks[band].push_back( - FrequancyPeak(fft_number, int(peak_magnitude), int(corrected_peak_frequency_bin), LOW_QUALITY_SAMPLE_RATE) - ); + FrequancyPeak(fft_number, static_cast(peak_magnitude), + static_cast(corrected_peak_frequency_bin), + LOW_QUALITY_SAMPLE_RATE)); } } } @@ -186,8 +202,8 @@ void SignatureGenerator::doPeakRecognition() void SignatureGenerator::resetSignatureGenerater() { - mNextSignature = Signature(16000, 0); - mRingBufferOfSamples = RingBuffer(2048, 0); - mFFTOutputs = RingBuffer(256, fft::RealArray(1025, 0.0)); - mSpreadFFTsOutput = RingBuffer(256, fft::RealArray(1025, 0.0)); -} \ No newline at end of file + next_signature_ = Signature(16000, 0); + samples_ring_buffer_ = RingBuffer(2048, 0); + fft_outputs_ = RingBuffer(256, fft::RealArray(1025, 0.0)); + spread_ffts_output_ = RingBuffer(256, fft::RealArray(1025, 0.0)); +} diff --git a/lib/algorithm/signature_generator.h b/lib/algorithm/signature_generator.h index 2c44043..94cbaff 100644 --- a/lib/algorithm/signature_generator.h +++ b/lib/algorithm/signature_generator.h @@ -1,44 +1,47 @@ -#ifndef SIGNATURE_GENERATOR_H -#define SIGNATURE_GENERATOR_H +#ifndef LIB_ALGORITHM_SIGNATURE_GENERATOR_H_ +#define LIB_ALGORITHM_SIGNATURE_GENERATOR_H_ - -#include "signature.h" -#include "../utils/ring_buffer.h" -#include "../audio/downsampler.h" -#include "../utils/fft.h" +#include "algorithm/signature.h" +#include "audio/downsampler.h" +#include "utils/fft.h" +#include "utils/ring_buffer.h" constexpr auto MAX_PEAKS = 255u; class SignatureGenerator { -public: + public: SignatureGenerator(); - void FeedInput(const LowQualityTrack& input); + void FeedInput(const LowQualityTrack &input); Signature GetNextSignature(); - inline void AddSampleProcessed(std::uint32_t sampleProcessed) - { mSampleProcessed += sampleProcessed;} + inline void AddSampleProcessed(std::uint32_t sample_processed) + { + sample_processed_ += sample_processed; + } - inline void SetMaxTimeSeconds(double maxTimeSeconds) - { mMaxTimeSeconds = maxTimeSeconds; } + inline void set_max_time_seconds(double max_time_seconds) + { + max_time_seconds_ = max_time_seconds; + } -private: - void processInput(const LowQualityTrack& input); - void doFFT(const LowQualityTrack& input); + private: + void processInput(const LowQualityTrack &input); + void doFFT(const LowQualityTrack &input); void doPeakSpreadingAndRecoginzation(); void doPeakSpreading(); void doPeakRecognition(); void resetSignatureGenerater(); -private: - LowQualityTrack mInputPendingProcessing; - std::uint32_t mSampleProcessed; - double mMaxTimeSeconds; + private: + LowQualityTrack input_pending_processing_; + std::uint32_t sample_processed_; + double max_time_seconds_; - Signature mNextSignature; - RingBuffer mRingBufferOfSamples; - RingBuffer mFFTOutputs; - RingBuffer mSpreadFFTsOutput; + Signature next_signature_; + RingBuffer samples_ring_buffer_; + RingBuffer fft_outputs_; + RingBuffer spread_ffts_output_; }; -#endif // SIGNATURE_GENERATOR_H +#endif // LIB_ALGORITHM_SIGNATURE_GENERATOR_H_ diff --git a/lib/audio/byte_control.h b/lib/audio/byte_control.h index 427deb7..1f95079 100644 --- a/lib/audio/byte_control.h +++ b/lib/audio/byte_control.h @@ -1,31 +1,29 @@ -#ifndef BYTE_CONTROL_H -#define BYTE_CONTROL_H +#ifndef LIB_AUDIO_BYTE_CONTROL_H_ +#define LIB_AUDIO_BYTE_CONTROL_H_ #include -#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i))) -#define GETINT8(cp, i) GETINTX(std::int8_t, (cp), (i)) -#define GETINT16(cp, i) GETINTX(std::int16_t, (cp), (i)) -#define GETINT32(cp, i) GETINTX(std::int32_t, (cp), (i)) -#define GETINT64(cp, i) GETINTX(std::int64_t, (cp), (i)) +#define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i))) // NOLINT [readability-casting] +#define GETINT8(cp, i) GETINTX(std::int8_t, (cp), (i)) +#define GETINT16(cp, i) GETINTX(std::int16_t, (cp), (i)) +#define GETINT32(cp, i) GETINTX(std::int32_t, (cp), (i)) +#define GETINT64(cp, i) GETINTX(std::int64_t, (cp), (i)) #ifdef WORDS_BIGENDIAN -#define GETINT24(cp, i) ( \ - ((unsigned char *)(cp) + (i))[2] + \ - (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ - (((signed char *)(cp) + (i))[0] * (1 << 16)) ) +#define GETINT24(cp, i) \ + (((unsigned char *)(cp) + (i))[2] + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[0] * (1 << 16))) #else -#define GETINT24(cp, i) ( \ - ((unsigned char *)(cp) + (i))[0] + \ - (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ - (((signed char *)(cp) + (i))[2] * (1 << 16)) ) +#define GETINT24(cp, i) \ + (((unsigned char *)(cp) + (i))[0] + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[2] * (1 << 16))) #endif -#define GETSAMPLE64(size, cp, i) ( \ - ((size) == 1) ? (std::int64_t)GETINT8((cp), (i)) * (1LL << 56) : \ - ((size) == 2) ? (std::int64_t)GETINT16((cp), (i)) * (1LL << 48) : \ - ((size) == 3) ? (std::int64_t)GETINT24((cp), (i)) * (1LL << 40) : \ - ((size) == 4) ? (std::int64_t)GETINT32((cp), (i)) * (1LL << 32) : \ - (std::int64_t)GETINT64((cp), (i)) ) +#define GETSAMPLE64(size, cp, i) \ + (((size) == 1) ? (std::int64_t)GETINT8((cp), (i)) * (1LL << 56) \ + : ((size) == 2) ? (std::int64_t)GETINT16((cp), (i)) * (1LL << 48) \ + : ((size) == 3) ? (std::int64_t)GETINT24((cp), (i)) * (1LL << 40) \ + : ((size) == 4) ? (std::int64_t)GETINT32((cp), (i)) * (1LL << 32) \ + : (std::int64_t)GETINT64((cp), (i))) -#endif // BYTE_CONTROL_H \ No newline at end of file +#endif // LIB_AUDIO_BYTE_CONTROL_H_ diff --git a/lib/audio/downsampler.cpp b/lib/audio/downsampler.cpp index 3e8ed75..dbaa531 100644 --- a/lib/audio/downsampler.cpp +++ b/lib/audio/downsampler.cpp @@ -1,40 +1,37 @@ -#include "downsampler.h" -#include "byte_control.h" -#include "wav.h" -#include +#include "audio/downsampler.h" #include +#include #include #include +#include "audio/byte_control.h" +#include "audio/wav.h" -LowQualityTrack Downsampler::GetLowQualityPCM(const Wav& wav, std::int32_t start_sec, std::int32_t end_sec) +LowQualityTrack Downsampler::GetLowQualityPCM(const Wav &wav, std::int32_t start_sec, + std::int32_t end_sec) { LowQualityTrack low_quality_pcm; - const auto channels = wav.GetChannel(); - const auto sample_rate = wav.GetSampleRate(); - const auto bits_per_sample = wav.GetBitPerSample(); - const auto data_size = wav.GetDataSize(); - const auto audio_format = wav.GetAudioFormat(); - const std::uint8_t* pcm_data = wav.GetData().get(); - - if (channels == 1 && - sample_rate == LOW_QUALITY_SAMPLE_RATE && - bits_per_sample == LOW_QUALITY_SAMPLE_BIT_WIDTH && - start_sec == 0 && - end_sec == -1) + const auto channels = wav.num_channels(); + const auto sample_rate = wav.sample_rate_(); + const auto bits_per_sample = wav.bits_per_sample(); + const auto data_size = wav.data_size(); + const auto audio_format = wav.audio_format(); + const std::uint8_t *pcm_data = wav.data().get(); + + if (channels == 1 && sample_rate == LOW_QUALITY_SAMPLE_RATE && + bits_per_sample == LOW_QUALITY_SAMPLE_BIT_WIDTH && start_sec == 0 && end_sec == -1) { // no need to convert low quality pcm. just copy raw data low_quality_pcm.resize(data_size); - std::memcpy(low_quality_pcm.data(), wav.GetData().get(), data_size); + std::memcpy(low_quality_pcm.data(), wav.data().get(), data_size); return low_quality_pcm; } - - - double downsample_ratio = sample_rate / (double)LOW_QUALITY_SAMPLE_RATE; + + double downsample_ratio = sample_rate / static_cast(LOW_QUALITY_SAMPLE_RATE); std::uint32_t width = bits_per_sample / 8; std::uint32_t sample_count = data_size / width; - const void* src_raw_data = pcm_data + (start_sec * sample_rate * width * channels); + const void *src_raw_data = pcm_data + (start_sec * sample_rate * width * channels); std::uint32_t new_sample_count = sample_count / channels / downsample_ratio; @@ -49,32 +46,18 @@ LowQualityTrack Downsampler::GetLowQualityPCM(const Wav& wav, std::int32_t start bool is_signed = audio_format == 1; downsample_func = getDownsampleFunc(is_signed, bits_per_sample, channels); - downsample_func( - &low_quality_pcm, - src_raw_data, - downsample_ratio, - new_sample_count, - width, - channels - ); - + downsample_func(&low_quality_pcm, src_raw_data, downsample_ratio, new_sample_count, width, + channels); return low_quality_pcm; } -#include - -DownsampleFunc Downsampler::getDownsampleFunc( - bool is_signed, - std::uint32_t width, - std::uint32_t channels) +DownsampleFunc Downsampler::getDownsampleFunc(bool is_signed, std::uint32_t width, + std::uint32_t channels) { channels = std::min(channels, 3u); width = is_signed ? 0 : width; - static std::map< - std::tuple, - DownsampleFunc> - func_map{ + static std::map, DownsampleFunc> func_map{ {std::make_tuple(true, 0, 1), &Downsampler::signedMonoToMono}, {std::make_tuple(true, 0, 2), &Downsampler::signedStereoToMono}, {std::make_tuple(true, 0, 3), &Downsampler::signedMultiToMono}, @@ -88,13 +71,9 @@ DownsampleFunc Downsampler::getDownsampleFunc( return func_map.at(std::make_tuple(is_signed, width, channels)); } -void Downsampler::signedMonoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::signedMonoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { std::uint32_t index = 0; for (std::uint32_t i = 0; i < new_sample_count; i++) @@ -104,31 +83,25 @@ void Downsampler::signedMonoToMono( } } -void Downsampler::signedStereoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::signedStereoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { std::uint32_t index = 0; for (std::uint32_t i = 0; i < new_sample_count; i++) { index = std::uint32_t(i * downsample_ratio) * width * channels; - LowQualitySample sample1 = GETSAMPLE64(width, src, index) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); - LowQualitySample sample2 = GETSAMPLE64(width, src, index + width) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); + LowQualitySample sample1 = + GETSAMPLE64(width, src, index) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); + LowQualitySample sample2 = + GETSAMPLE64(width, src, index + width) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); dst->at(i) = (sample1 + sample2) / 2; } } -void Downsampler::signedMultiToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::signedMultiToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { double collected_sample = 0; std::uint32_t index = 0; @@ -138,20 +111,17 @@ void Downsampler::signedMultiToMono( for (std::uint32_t k = 0; k < channels; k++) { index = std::uint32_t(i * downsample_ratio) * width * channels; - collected_sample += GETSAMPLE64(width, src, index + k * width) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); + collected_sample += + GETSAMPLE64(width, src, index + k * width) >> (64 - LOW_QUALITY_SAMPLE_BIT_WIDTH); } dst->at(i) = LowQualitySample(collected_sample / channels); } } template -void Downsampler::floatMonoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::floatMonoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { T temp_float_sample = 0; std::uint64_t temp_sample = 0; @@ -160,19 +130,15 @@ void Downsampler::floatMonoToMono( { index = std::uint32_t(i * downsample_ratio) * width * channels; temp_sample = GETSAMPLE64(width, src, index) >> (64 - sizeof(T) * 8); - temp_float_sample = *reinterpret_cast(&temp_sample); + temp_float_sample = *reinterpret_cast(&temp_sample); dst->at(i) = LowQualitySample(temp_float_sample * LOW_QUALITY_SAMPLE_MAX); } } template -void Downsampler::floatStereoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::floatStereoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { std::uint64_t temp_sample1 = 0; std::uint64_t temp_sample2 = 0; @@ -184,20 +150,17 @@ void Downsampler::floatStereoToMono( index = std::uint32_t(i * downsample_ratio) * width * channels; temp_sample1 = GETSAMPLE64(width, src, index) >> (64 - sizeof(T) * 8); temp_sample2 = GETSAMPLE64(width, src, index + width) >> (64 - sizeof(T) * 8); - temp_float_sample1 = *reinterpret_cast(&temp_sample1); - temp_float_sample2 = *reinterpret_cast(&temp_sample2); - dst->at(i) = LowQualitySample((temp_float_sample1 + temp_float_sample2) / 2 * LOW_QUALITY_SAMPLE_MAX); + temp_float_sample1 = *reinterpret_cast(&temp_sample1); + temp_float_sample2 = *reinterpret_cast(&temp_sample2); + dst->at(i) = LowQualitySample((temp_float_sample1 + temp_float_sample2) / 2 * + LOW_QUALITY_SAMPLE_MAX); } } template -void Downsampler::floatMultiToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels) +void Downsampler::floatMultiToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels) { std::uint32_t index = 0; T collected_sample = 0; @@ -209,7 +172,7 @@ void Downsampler::floatMultiToMono( for (std::uint32_t k = 0; k < channels; k++) { temp_sample = GETSAMPLE64(width, src, index + k * width) >> (64 - sizeof(T) * 8); - collected_sample += *reinterpret_cast(&temp_sample); + collected_sample += *reinterpret_cast(&temp_sample); } dst->at(i) = LowQualitySample(collected_sample / channels * LOW_QUALITY_SAMPLE_MAX); } diff --git a/lib/audio/downsampler.h b/lib/audio/downsampler.h index 37560bc..bae4a27 100644 --- a/lib/audio/downsampler.h +++ b/lib/audio/downsampler.h @@ -1,5 +1,5 @@ -#ifndef DOWNSAMPLER_H -#define DOWNSAMPLER_H +#ifndef LIB_AUDIO_DOWNSAMPLER_H_ +#define LIB_AUDIO_DOWNSAMPLER_H_ #include #include @@ -15,76 +15,41 @@ constexpr std::uint32_t LOW_QUALITY_SAMPLE_RATE = 16000; constexpr std::uint32_t LOW_QUALITY_SAMPLE_BIT_WIDTH = sizeof(LowQualitySample) * 8; constexpr std::uint32_t LOW_QUALITY_SAMPLE_MAX = 32767; -using DownsampleFunc = void(*)(LowQualityTrack*, const void*, double, std::uint32_t, std::uint32_t, std::uint32_t); +using DownsampleFunc = void (*)(LowQualityTrack *, const void *, double, std::uint32_t, + std::uint32_t, std::uint32_t); class Downsampler { -public: - static LowQualityTrack GetLowQualityPCM( - const Wav& wav, - std::int32_t start_sec = 0, - std::int32_t end_sec = -1 - ); - -private: - static DownsampleFunc getDownsampleFunc( - bool is_signed, - std::uint32_t width, - std::uint32_t channels - ); - - static void signedStereoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); - static void signedMonoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); - static void signedMultiToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); + public: + static LowQualityTrack GetLowQualityPCM(const Wav &wav, std::int32_t start_sec = 0, + std::int32_t end_sec = -1); + + private: + static DownsampleFunc getDownsampleFunc(bool is_signed, std::uint32_t width, + std::uint32_t channels); + + static void signedStereoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); + static void signedMonoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); + static void signedMultiToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); template - static void floatStereoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); + static void floatStereoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); template - static void floatMonoToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); + static void floatMonoToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); template - static void floatMultiToMono( - LowQualityTrack* dst, - const void* src, - double downsample_ratio, - std::uint32_t new_sample_count, - std::uint32_t width, - std::uint32_t channels - ); + static void floatMultiToMono(LowQualityTrack *dst, const void *src, double downsample_ratio, + std::uint32_t new_sample_count, std::uint32_t width, + std::uint32_t channels); }; -#endif // DOWNSAMPLER_H \ No newline at end of file +#endif // LIB_AUDIO_DOWNSAMPLER_H_ diff --git a/lib/audio/wav.cpp b/lib/audio/wav.cpp index c290332..f4dbadd 100644 --- a/lib/audio/wav.cpp +++ b/lib/audio/wav.cpp @@ -1,16 +1,16 @@ -#include "wav.h" +#include "audio/wav.h" #include +#include +#include #include #include +#include #include -#include -#include -#include -Wav Wav::FromFile(const std::string& wav_file_path) +Wav Wav::FromFile(const std::string &wav_file_path) { Wav wav; - wav.mWavFilePath = wav_file_path; + wav.wav_file_path_ = wav_file_path; std::ifstream stream(wav_file_path, std::ios::binary); if (!stream.is_open()) { @@ -20,7 +20,7 @@ Wav Wav::FromFile(const std::string& wav_file_path) return wav; } -Wav Wav::FromRawWav(const char* raw_wav, std::uint32_t raw_wav_size) +Wav Wav::FromRawWav(const char *raw_wav, std::uint32_t raw_wav_size) { Wav wav; std::istringstream stream(std::string(raw_wav, raw_wav_size)); @@ -28,82 +28,67 @@ Wav Wav::FromRawWav(const char* raw_wav, std::uint32_t raw_wav_size) return wav; } -Wav Wav::FromSignedPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, - std::uint32_t sample_rate, std::uint32_t sample_width, - std::uint32_t channel_count) +Wav Wav::FromSignedPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, std::uint32_t sample_rate, + std::uint32_t sample_width, std::uint32_t channel_count) { - return fromPCM( - raw_pcm, - raw_pcm_size, - AudioFormat::PCM_INTEGER, - sample_rate, - sample_width, - channel_count - ); + return fromPCM(raw_pcm, raw_pcm_size, AudioFormat::PCM_INTEGER, sample_rate, sample_width, + channel_count); } -Wav Wav::FromFloatPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, - std::uint32_t sample_rate, std::uint32_t sample_width, - std::uint32_t channel_count) +Wav Wav::FromFloatPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, std::uint32_t sample_rate, + std::uint32_t sample_width, std::uint32_t channel_count) { - return fromPCM( - raw_pcm, - raw_pcm_size, - AudioFormat::PCM_FLOAT, - sample_rate, - sample_width, - channel_count - ); + return fromPCM(raw_pcm, raw_pcm_size, AudioFormat::PCM_FLOAT, sample_rate, sample_width, + channel_count); } Wav::~Wav() { } -Wav Wav::fromPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, - AudioFormat audio_format, std::uint32_t sample_rate, - std::uint32_t sample_width, std::uint32_t channel_count) +Wav Wav::fromPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, AudioFormat audio_format, + std::uint32_t sample_rate, std::uint32_t sample_width, std::uint32_t channel_count) { Wav wav; - wav.mHeader.file_size = sizeof(WavHeader) + sizeof(FmtSubchunk) + 8 + raw_pcm_size; - wav.mFmt.audio_format = static_cast(audio_format); - wav.mFmt.num_channels = channel_count; - wav.mFmt.sample_rate = sample_rate; - wav.mFmt.byte_rate = sample_rate * channel_count * sample_width / 8; - wav.mFmt.block_align = channel_count * sample_width / 8; - wav.mFmt.bits_per_sample = sample_width; - wav.mDataSize = raw_pcm_size; - wav.mData.reset(new std::uint8_t[raw_pcm_size]); - std::memcpy(wav.mData.get(), raw_pcm, raw_pcm_size); + wav.header_.file_size = sizeof(WavHeader) + sizeof(FmtSubchunk) + 8 + raw_pcm_size; + wav.fmt_.audio_format = static_cast(audio_format); + wav.fmt_.num_channels = channel_count; + wav.fmt_.sample_rate = sample_rate; + wav.fmt_.byte_rate = sample_rate * channel_count * sample_width / 8; + wav.fmt_.block_align = channel_count * sample_width / 8; + wav.fmt_.bits_per_sample = sample_width; + wav.data_size_ = raw_pcm_size; + wav.data_.reset(new std::uint8_t[raw_pcm_size]); + std::memcpy(wav.data_.get(), raw_pcm, raw_pcm_size); return wav; } -void Wav::readWavFileBuffer(std::istream& stream) +void Wav::readWavFileBuffer(std::istream &stream) { - stream.read(reinterpret_cast(&mHeader), sizeof(WavHeader)); + stream.read(reinterpret_cast(&header_), sizeof(WavHeader)); - const auto SUBCHUNK_LIMIT = 10; + const auto kSubchunkLimit = 10; bool data_chunk_found = false; bool fmt_chunk_found = false; - for (int i = 0; i < SUBCHUNK_LIMIT && stream.tellg() < mHeader.file_size - 8; i++) + for (int i = 0; i < kSubchunkLimit && stream.tellg() < header_.file_size - 8; i++) { char subchunk_id[4]; stream.read(subchunk_id, 4); - + std::uint32_t subchunk_size; - stream.read(reinterpret_cast(&subchunk_size), 4); + stream.read(reinterpret_cast(&subchunk_size), 4); if (strncmp(subchunk_id, "data", 4) == 0) - { - mDataSize = subchunk_size; - mData.reset(new std::uint8_t[mDataSize]); - stream.read(reinterpret_cast(mData.get()), mDataSize); + { + data_size_ = subchunk_size; + data_.reset(new std::uint8_t[data_size_]); + stream.read(reinterpret_cast(data_.get()), data_size_); data_chunk_found = true; } else if (strncmp(subchunk_id, "fmt ", 4) == 0) { - stream.read(reinterpret_cast(&mFmt), sizeof(FmtSubchunk)); + stream.read(reinterpret_cast(&fmt_), sizeof(FmtSubchunk)); fmt_chunk_found = true; } else @@ -116,10 +101,9 @@ void Wav::readWavFileBuffer(std::istream& stream) return; // read wav successfully } } - + if (!data_chunk_found || !fmt_chunk_found) { throw std::runtime_error("Invalid WAV file"); } } - diff --git a/lib/audio/wav.h b/lib/audio/wav.h index 8bc6daa..d9f60c3 100644 --- a/lib/audio/wav.h +++ b/lib/audio/wav.h @@ -1,18 +1,19 @@ -#ifndef WAV_H -#define WAV_H +#ifndef LIB_AUDIO_WAV_H_ +#define LIB_AUDIO_WAV_H_ -#include -#include #include -#include "byte_control.h" +#include +#include "audio/byte_control.h" -struct WavHeader { +struct WavHeader +{ char riff_header[4]; // "RIFF" std::uint32_t file_size; char wave_header[4]; // "WAVE" }; -struct FmtSubchunk { +struct FmtSubchunk +{ std::uint16_t audio_format; // 1 = PCM, 3 = IEEE float, etc. std::uint16_t num_channels; std::uint32_t sample_rate; @@ -21,48 +22,69 @@ struct FmtSubchunk { std::uint16_t bits_per_sample; }; -enum class AudioFormat { +enum class AudioFormat +{ PCM_INTEGER = 1, PCM_FLOAT = 3, }; - class Wav { -public: - Wav(Wav&&) = default; - Wav(const Wav&) = delete; - static Wav FromFile(const std::string& wav_file_path); - static Wav FromRawWav(const char* raw_wav, std::uint32_t raw_wav_size); - static Wav FromSignedPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, - std::uint32_t sample_rate, std::uint32_t sample_width, - std::uint32_t channel_count); - static Wav FromFloatPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, - std::uint32_t sample_rate, std::uint32_t sample_width, - std::uint32_t channel_count); + public: + Wav(Wav &&) = default; + Wav(const Wav &) = delete; + static Wav FromFile(const std::string &wav_file_path); + static Wav FromRawWav(const char *raw_wav, std::uint32_t raw_wav_size); + static Wav FromSignedPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, + std::uint32_t sample_rate, std::uint32_t sample_width, + std::uint32_t channel_count); + static Wav FromFloatPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, + std::uint32_t sample_rate, std::uint32_t sample_width, + std::uint32_t channel_count); ~Wav(); - inline std::uint16_t GetAudioFormat() const { return mFmt.audio_format; } - inline std::uint16_t GetChannel() const { return mFmt.num_channels; } - inline std::uint32_t GetSampleRate() const { return mFmt.sample_rate; } - inline std::uint32_t GetBitPerSample() const { return mFmt.bits_per_sample; } - inline std::uint32_t GetDataSize() const { return mDataSize; } - inline std::uint32_t GetFileSize() const { return mHeader.file_size; } - inline const std::unique_ptr& GetData() const { return mData; } + inline std::uint16_t audio_format() const + { + return fmt_.audio_format; + } + inline std::uint16_t num_channels() const + { + return fmt_.num_channels; + } + inline std::uint32_t sample_rate_() const + { + return fmt_.sample_rate; + } + inline std::uint32_t bits_per_sample() const + { + return fmt_.bits_per_sample; + } + inline std::uint32_t data_size() const + { + return data_size_; + } + inline std::uint32_t file_size() const + { + return header_.file_size; + } + inline const std::unique_ptr &data() const + { + return data_; + } -private: + private: Wav() = default; - static Wav fromPCM(const char* raw_pcm, std::uint32_t raw_pcm_size, AudioFormat audio_format, - std::uint32_t sample_rate, std::uint32_t sample_width, - std::uint32_t channel_count); - void readWavFileBuffer(std::istream& stream); + static Wav fromPCM(const char *raw_pcm, std::uint32_t raw_pcm_size, AudioFormat audio_format, + std::uint32_t sample_rate, std::uint32_t sample_width, + std::uint32_t channel_count); + void readWavFileBuffer(std::istream &stream); -private: - WavHeader mHeader; - FmtSubchunk mFmt; - std::string mWavFilePath; - std::uint32_t mDataSize; - std::unique_ptr mData; + private: + WavHeader header_; + FmtSubchunk fmt_; + std::string wav_file_path_; + std::uint32_t data_size_; + std::unique_ptr data_; }; -#endif // WAV_H \ No newline at end of file +#endif // LIB_AUDIO_WAV_H_ diff --git a/lib/communication/shazam.cpp b/lib/communication/shazam.cpp index 59f157c..5fb9ff3 100644 --- a/lib/communication/shazam.cpp +++ b/lib/communication/shazam.cpp @@ -1,11 +1,11 @@ -#include "shazam.h" -#include "user_agents.h" -#include "timezones.h" -#include "../utils/uuid4.h" -#include "../algorithm/signature.h" +#include "communication/shazam.h" +#include #include #include -#include +#include "algorithm/signature.h" +#include "communication/timezones.h" +#include "communication/user_agents.h" +#include "utils/uuid4.h" // static variables initialization constexpr char Shazam::HOST[]; @@ -13,18 +13,24 @@ constexpr char Shazam::HOST[]; std::string Shazam::GetShazamHost() { std::string host = HOST + uuid4::generate() + "/" + uuid4::generate(); - host += "?sync=true&webv3=true&sampling=true&connected=&shazamapiversion=v3&sharehub=true&video=v3"; + host += "?sync=true&" + "webv3=true&" + "sampling=true&" + "connected=&" + "shazamapiversion=v3&" + "sharehub=true&" + "video=v3"; return host; } -std::string Shazam::GetRequestContent(const std::string& uri, unsigned int sample_ms) +std::string Shazam::GetRequestContent(const std::string &uri, unsigned int sample_ms) { std::mt19937 gen(std::random_device{}()); std::uniform_int_distribution<> dis_float(0.0, 1.0); - - auto timezone = getTimezone(); + + auto timezone = getTimezone(); double fuzz = dis_float(gen) * 15.3 - 7.65; - + std::stringstream json_buf; json_buf << "{"; json_buf << "\"geolocation\":{"; @@ -38,7 +44,8 @@ std::string Shazam::GetRequestContent(const std::string& uri, unsigned int sampl json_buf << "\"uri\":\"" << uri << "\""; json_buf << "},"; json_buf << "\"timestamp\":" << time(nullptr) * 1000ULL << ","; - json_buf << "\"timezone\":" << "\"" << timezone << "\""; + json_buf << "\"timezone\":" + << "\"" << timezone << "\""; json_buf << "}"; std::string content = json_buf.str(); return content; @@ -56,4 +63,4 @@ std::string Shazam::getTimezone() std::mt19937 gen(std::random_device{}()); std::uniform_int_distribution<> dis_timezone(0, EUROPE_TIMEZONES_SIZE - 1); return EUROPE_TIMEZONES[dis_timezone(gen)]; -} \ No newline at end of file +} diff --git a/lib/communication/shazam.h b/lib/communication/shazam.h index 6b17a4f..16c43b6 100644 --- a/lib/communication/shazam.h +++ b/lib/communication/shazam.h @@ -1,23 +1,19 @@ -#ifndef __SHAZAM_H__ -#define __SHAZAM_H__ +#ifndef LIB_COMMUNICATION_SHAZAM_H_ +#define LIB_COMMUNICATION_SHAZAM_H_ #include -// forward declaration -class Signature; - -class Shazam +class Shazam { static constexpr char HOST[] = "https://amp.shazam.com/discovery/v5/fr/FR/android/-/tag/"; -public: + public: static std::string GetShazamHost(); static std::string GetUserAgent(); - static std::string GetRequestContent(const std::string& uri, unsigned int sample_ms); + static std::string GetRequestContent(const std::string &uri, unsigned int sample_ms); -private: + private: static std::string getTimezone(); }; - -#endif // __SHAZAM_H__ \ No newline at end of file +#endif // LIB_COMMUNICATION_SHAZAM_H_ diff --git a/lib/communication/timezones.h b/lib/communication/timezones.h index 9659149..608dbf0 100644 --- a/lib/communication/timezones.h +++ b/lib/communication/timezones.h @@ -1,69 +1,24 @@ -#ifndef __TIMEZONES_H__ -#define __TIMEZONES_H__ +#ifndef LIB_COMMUNICATION_TIMEZONES_H_ +#define LIB_COMMUNICATION_TIMEZONES_H_ -static constexpr const char* EUROPE_TIMEZONES[] = { - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Astrakhan", - "Europe/Athens", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Bratislava", - "Europe/Brussels", - "Europe/Bucharest", - "Europe/Budapest", - "Europe/Busingen", - "Europe/Chisinau", - "Europe/Copenhagen", - "Europe/Dublin", - "Europe/Gibraltar", - "Europe/Guernsey", - "Europe/Helsinki", - "Europe/Isle_of_Man", - "Europe/Istanbul", - "Europe/Jersey", - "Europe/Kaliningrad", - "Europe/Kiev", - "Europe/Kirov", - "Europe/Lisbon", - "Europe/Ljubljana", - "Europe/London", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Mariehamn", - "Europe/Minsk", - "Europe/Monaco", - "Europe/Moscow", - "Europe/Oslo", - "Europe/Paris", - "Europe/Podgorica", - "Europe/Prague", - "Europe/Riga", - "Europe/Rome", - "Europe/Samara", - "Europe/San_Marino", - "Europe/Sarajevo", - "Europe/Saratov", - "Europe/Simferopol", - "Europe/Skopje", - "Europe/Sofia", - "Europe/Stockholm", - "Europe/Tallinn", - "Europe/Tirane", - "Europe/Ulyanovsk", - "Europe/Uzhgorod", - "Europe/Vaduz", - "Europe/Vatican", - "Europe/Vienna", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Warsaw", - "Europe/Zagreb", - "Europe/Zaporozhye", - "Europe/Zurich" -}; +static constexpr const char *EUROPE_TIMEZONES[] = { + "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", + "Europe/Belgrade", "Europe/Berlin", "Europe/Bratislava", "Europe/Brussels", + "Europe/Bucharest", "Europe/Budapest", "Europe/Busingen", "Europe/Chisinau", + "Europe/Copenhagen", "Europe/Dublin", "Europe/Gibraltar", "Europe/Guernsey", + "Europe/Helsinki", "Europe/Isle_of_Man", "Europe/Istanbul", "Europe/Jersey", + "Europe/Kaliningrad", "Europe/Kiev", "Europe/Kirov", "Europe/Lisbon", + "Europe/Ljubljana", "Europe/London", "Europe/Luxembourg", "Europe/Madrid", + "Europe/Malta", "Europe/Mariehamn", "Europe/Minsk", "Europe/Monaco", + "Europe/Moscow", "Europe/Oslo", "Europe/Paris", "Europe/Podgorica", + "Europe/Prague", "Europe/Riga", "Europe/Rome", "Europe/Samara", + "Europe/San_Marino", "Europe/Sarajevo", "Europe/Saratov", "Europe/Simferopol", + "Europe/Skopje", "Europe/Sofia", "Europe/Stockholm", "Europe/Tallinn", + "Europe/Tirane", "Europe/Ulyanovsk", "Europe/Uzhgorod", "Europe/Vaduz", + "Europe/Vatican", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", + "Europe/Warsaw", "Europe/Zagreb", "Europe/Zaporozhye", "Europe/Zurich"}; -const static unsigned int EUROPE_TIMEZONES_SIZE = sizeof(EUROPE_TIMEZONES) / sizeof(EUROPE_TIMEZONES[0]); +constexpr unsigned int EUROPE_TIMEZONES_SIZE = + sizeof(EUROPE_TIMEZONES) / sizeof(EUROPE_TIMEZONES[0]); -#endif // __TIMEZONES_H__ \ No newline at end of file +#endif // LIB_COMMUNICATION_TIMEZONES_H_ diff --git a/lib/communication/user_agents.h b/lib/communication/user_agents.h index ae85c9c..365b4db 100644 --- a/lib/communication/user_agents.h +++ b/lib/communication/user_agents.h @@ -1,11 +1,11 @@ -#ifndef __USER_AGENTS_H__ -#define __USER_AGENTS_H__ +#ifndef LIB_COMMUNICATION_USER_AGENTS_H_ +#define LIB_COMMUNICATION_USER_AGENTS_H_ -// +// // https://github.com/SaswatPadhi/FlashProfileDemo/blob/c1e3f05d09f6443568a606dc0a439d6ebb057ae1/tests/hetero/user_agents.json // -static constexpr const char* USER_AGENTS[] = { +static constexpr const char *USER_AGENTS[] = { "Dalvik/2.1.0 (Linux; U; Android 5.0.2; VS980 4G Build/LRX22G)", "Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-T210 Build/KOT49H)", "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-P905V Build/LMY47X)", @@ -105,9 +105,8 @@ static constexpr const char* USER_AGENTS[] = { "Dalvik/2.1.0 (Linux; U; Android 6.0.1; SM-J700T Build/MMB29K)", "Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-J500FN Build/LMY48B)", "Dalvik/1.6.0 (Linux; U; Android 4.2.2; SM-T217S Build/JDQ39)", - "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SAMSUNG-SM-N900A Build/KTU84P)" -}; + "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SAMSUNG-SM-N900A Build/KTU84P)"}; constexpr unsigned int USER_AGENTS_SIZE = sizeof(USER_AGENTS) / sizeof(USER_AGENTS[0]); -#endif // __USER_AGENTS_H__ \ No newline at end of file +#endif // LIB_COMMUNICATION_USER_AGENTS_H_ diff --git a/lib/utils/base64.h b/lib/utils/base64.h index 14b10de..f27c1a2 100644 --- a/lib/utils/base64.h +++ b/lib/utils/base64.h @@ -1,58 +1,55 @@ -#ifndef __BASE64_H__ -#define __BASE64_H__ +#ifndef LIB_UTILS_BASE64_H_ +#define LIB_UTILS_BASE64_H_ #include namespace base64 { - static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; +static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; +std::string encode(const char *bytes_to_encode, unsigned int in_len) +{ + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; - std::string encode(const char *bytes_to_encode, unsigned int in_len) + while (in_len--) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) - { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) - { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (i = 0; (i < 4); i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { - for (j = i; j < 3; j++) - char_array_3[j] = '\0'; - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while ((i++ < 3)) - ret += '='; + for (i = 0; (i < 4); i++) + ret += base64_chars[char_array_4[i]]; + i = 0; } + } + + if (i) + { + for (j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; - return ret; + while ((i++ < 3)) + ret += '='; } + return ret; } +} // namespace base64 -#endif // __BASE64_H__ +#endif // LIB_UTILS_BASE64_H_ diff --git a/lib/utils/crc32.h b/lib/utils/crc32.h index 0450f9c..1f38fe5 100644 --- a/lib/utils/crc32.h +++ b/lib/utils/crc32.h @@ -1,31 +1,28 @@ -#ifndef __CRC32_H__ -#define __CRC32_H__ - -#include +#ifndef LIB_UTILS_CRC32_H_ +#define LIB_UTILS_CRC32_H_ namespace crc32 { - std::uint32_t crc32(const char* buf, std::size_t len) +std::uint32_t crc32(const char *buf, std::size_t len) +{ + std::uint32_t crc_table[256]; + std::uint32_t crc; + std::size_t i, j; + + for (i = 0; i < 256; i++) { - std::uint32_t crc_table[256]; - std::uint32_t crc; - std::size_t i, j; - - for (i = 0; i < 256; i++) - { - crc = i; - for (j = 0; j < 8; j++) - crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1; - crc_table[i] = crc; - }; - - crc = 0xFFFFFFFFUL; - - while (len--) - crc = crc_table[(crc ^ *buf++) & 0xFF] ^ (crc >> 8); - - return crc ^ 0xFFFFFFFFUL; - } + crc = i; + for (j = 0; j < 8; j++) + crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320UL : crc >> 1; + crc_table[i] = crc; + }; + crc = 0xFFFFFFFFUL; + + while (len--) + crc = crc_table[(crc ^ *buf++) & 0xFF] ^ (crc >> 8); + + return crc ^ 0xFFFFFFFFUL; } +} // namespace crc32 -#endif // __CRC32_H__ +#endif // LIB_UTILS_CRC32_H_ diff --git a/lib/utils/ffmpeg.h b/lib/utils/ffmpeg.h index a6489ec..abd2b95 100644 --- a/lib/utils/ffmpeg.h +++ b/lib/utils/ffmpeg.h @@ -1,116 +1,121 @@ -#ifndef __FFMPEG_H__ -#define __FFMPEG_H__ +#ifndef LIB_UTILS_FFMPEG_H_ +#define LIB_UTILS_FFMPEG_H_ -#include #include -#include +#include #include +#include #include -#include -#include "../audio/downsampler.h" +#include +#include "audio/downsampler.h" namespace ffmpeg { - constexpr const char* DEFAULT_FFMPEG_PATHS[] = {"ffmpeg", "ffmpeg.exe"}; - constexpr const char FFMPEG_PATH_ENV[] = "FFMPEG_PATH"; - constexpr int EXPECTED_DURATION = 5 * 60; // 5 minutes - class FFmpegWrapper - { - public: - FFmpegWrapper() = delete; - static int convertToWav(const std::string &input_file, LowQualityTrack* pcm); +constexpr const char *DEFAULT_FFMPEG_PATHS[] = {"ffmpeg", "ffmpeg.exe"}; +constexpr const char FFMPEG_PATH_ENV[] = "FFMPEG_PATH"; +constexpr int EXPECTED_DURATION = 5 * 60; // 5 minutes + +class FFmpegWrapper +{ + public: + FFmpegWrapper() = delete; + static int ConvertToWav(const std::string &input_file, LowQualityTrack *pcm); + + private: + static std::string getFFmpegPath(); + static bool isWindows(); - private: - static std::string getFFmpegPath(); - static bool isWindows(); + private: + static std::string ffmpeg_path_; +}; - private: - static std::string ffmpeg_path_; - }; +std::string FFmpegWrapper::ffmpeg_path_; // NOLINT - std::string FFmpegWrapper::ffmpeg_path_; // static member initialization - - int FFmpegWrapper::convertToWav(const std::string &input_file, LowQualityTrack* pcm) +int FFmpegWrapper::ConvertToWav(const std::string &input_file, LowQualityTrack *pcm) +{ + std::string ffmpeg_path = FFmpegWrapper::getFFmpegPath(); + if (ffmpeg_path.empty()) { - std::string ffmpeg_path = FFmpegWrapper::getFFmpegPath(); - if (ffmpeg_path.empty()) - { - std::cerr << "FFmpeg not found on system. Please install FFmpeg or set the "; - std::cerr << FFMPEG_PATH_ENV << " environment variable." << std::endl; - throw std::runtime_error("FFmpeg not found"); - } + std::cerr << "FFmpeg not found on system. Please install FFmpeg or set the "; + std::cerr << FFMPEG_PATH_ENV << " environment variable." << std::endl; + throw std::runtime_error("FFmpeg not found"); + } - std::stringstream ss; - ss << ffmpeg_path; - ss << " -i " << input_file; - ss << " -f " << "s" << LOW_QUALITY_SAMPLE_BIT_WIDTH << "le"; - ss << " -acodec " << "pcm_s" << LOW_QUALITY_SAMPLE_BIT_WIDTH << "le"; - ss << " -ar " << LOW_QUALITY_SAMPLE_RATE; - ss << " -ac " << 1; - ss << " - 2>/dev/null"; // suppress std - - std::FILE *pipe = popen(ss.str().c_str(), "r"); - if (!pipe) - { - throw std::runtime_error("popen() failed!"); - } + std::stringstream ss; + ss << ffmpeg_path; + ss << " -i " << input_file; + ss << " -f " + << "s" << LOW_QUALITY_SAMPLE_BIT_WIDTH << "le"; + ss << " -acodec " + << "pcm_s" << LOW_QUALITY_SAMPLE_BIT_WIDTH << "le"; + ss << " -ar " << LOW_QUALITY_SAMPLE_RATE; + ss << " -ac " << 1; + ss << " - 2>/dev/null"; // suppress std + + std::FILE *pipe = popen(ss.str().c_str(), "r"); + if (!pipe) + { + throw std::runtime_error("popen() failed!"); + } - std::array buffer; - size_t bytes_read; + std::array buffer; + size_t bytes_read; - pcm->reserve(EXPECTED_DURATION * LOW_QUALITY_SAMPLE_RATE); + pcm->reserve(EXPECTED_DURATION * LOW_QUALITY_SAMPLE_RATE); - while ((bytes_read = fread(buffer.data(), 1, buffer.size(), pipe)) != 0) - { - pcm->insert(pcm->end(), buffer.begin(), buffer.begin() + (bytes_read / sizeof(LowQualitySample))); - } + while ((bytes_read = fread(buffer.data(), 1, buffer.size(), pipe)) != 0) + { + pcm->insert(pcm->end(), buffer.begin(), + buffer.begin() + (bytes_read / sizeof(LowQualitySample))); + } + + pclose(pipe); + return 0; +} - pclose(pipe); - return 0; +std::string FFmpegWrapper::getFFmpegPath() +{ + if (!FFmpegWrapper::ffmpeg_path_.empty()) + { + return FFmpegWrapper::ffmpeg_path_; } - std::string FFmpegWrapper::getFFmpegPath() + const char *ffmpeg_env = std::getenv(FFMPEG_PATH_ENV); + if (ffmpeg_env) { - if (!FFmpegWrapper::ffmpeg_path_.empty()) - { - return FFmpegWrapper::ffmpeg_path_; - } + FFmpegWrapper::ffmpeg_path_ = ffmpeg_env; + return ffmpeg_env; + } - const char* ffmpeg_env = std::getenv(FFMPEG_PATH_ENV); - if (ffmpeg_env) - { - FFmpegWrapper::ffmpeg_path_ = ffmpeg_env; - return ffmpeg_env; - } - - std::string path = std::getenv("PATH"); - std::istringstream ss(path); - std::string token; - char delimiter = isWindows() ? ';' : ':'; - while (std::getline(ss, token, delimiter)) + std::string path = std::getenv("PATH"); + std::istringstream ss(path); + std::string token; + char delimiter = isWindows() ? ';' : ':'; + while (std::getline(ss, token, delimiter)) + { + for (const char *ffmpeg_path : DEFAULT_FFMPEG_PATHS) { - for (const char* ffmpeg_path : DEFAULT_FFMPEG_PATHS) + std::string full_path = token + "/" + ffmpeg_path; + if (std::ifstream(full_path).good()) { - std::string full_path = token + "/" + ffmpeg_path; - if (std::ifstream(full_path).good()) - { - FFmpegWrapper::ffmpeg_path_ = full_path; - return full_path; - } + FFmpegWrapper::ffmpeg_path_ = full_path; + return full_path; } } - return ""; // empty string means FFmpeg not found } + return ""; // empty string means FFmpeg not found +} - bool FFmpegWrapper::isWindows() - { - #if defined(_WIN32) || defined(_WIN64) - return true; - #endif // _WIN32 +bool FFmpegWrapper::isWindows() +{ +#if defined(_WIN32) || defined(_WIN64) + return true; +#endif // _WIN32 - return false; - } + return false; } -#endif // __FFMPEG_H__ +} // namespace ffmpeg + +#endif // LIB_UTILS_FFMPEG_H_ diff --git a/lib/utils/fft.h b/lib/utils/fft.h index 6cd8c30..a19f500 100644 --- a/lib/utils/fft.h +++ b/lib/utils/fft.h @@ -1,65 +1,66 @@ -#ifndef FFT_H -#define FFT_H +#ifndef LIB_UTILS_FFT_H_ +#define LIB_UTILS_FFT_H_ -#include #include -#include #include +#include // NOLINT [include_order] +#include namespace fft { - using RealArray = std::vector; - class FFT +using RealArray = std::vector; + +class FFT +{ + public: + template static RealArray RFFT(const Iterable &input) { - public: - template - static RealArray RFFT(const Iterable& input) + // If input size is 0, return false. + if (input.empty()) { - // If input size is 0, return false. - if (input.empty()) - { - throw std::invalid_argument("Input size cannot be 0"); - } + throw std::invalid_argument("Input size cannot be 0"); + } - std::size_t input_size = input.size(); - RealArray real_output(input_size / 2 + 1); + std::size_t input_size = input.size(); + RealArray real_output(input_size / 2 + 1); - double* in = fftw_alloc_real(input_size); - fftw_complex* out = fftw_alloc_complex(input_size / 2 + 1); + double *in = fftw_alloc_real(input_size); + fftw_complex *out = fftw_alloc_complex(input_size / 2 + 1); - // Copy and convert the input data to double - for (std::size_t i = 0; i < input_size; i++) - { - in[i] = static_cast(input[i]); - } + // Copy and convert the input data to double + for (std::size_t i = 0; i < input_size; i++) + { + in[i] = static_cast(input[i]); + } - fftw_plan plan = fftw_plan_dft_r2c_1d(input_size, in, out, FFTW_ESTIMATE); - fftw_execute(plan); + fftw_plan plan = fftw_plan_dft_r2c_1d(input_size, in, out, FFTW_ESTIMATE); + fftw_execute(plan); - double real_val = 0.0; - double imag_val = 0.0; - const double min_val = 1e-10; - const double scale_factor = 1.0 / (1 << 17); + double real_val = 0.0; + double imag_val = 0.0; + const double min_val = 1e-10; + const double scale_factor = 1.0 / (1 << 17); - // do max((real^2 + imag^2) / (1 << 17), 0.0000000001) - for (std::size_t i = 0; i < input_size / 2 + 1; ++i) - { - real_val = out[i][0]; - imag_val = out[i][1]; + // do max((real^2 + imag^2) / (1 << 17), 0.0000000001) + for (std::size_t i = 0; i < input_size / 2 + 1; ++i) + { + real_val = out[i][0]; + imag_val = out[i][1]; - real_val = (real_val * real_val + imag_val * imag_val) * scale_factor; - real_output[i] = (real_val < min_val) ? min_val : real_val; - } + real_val = (real_val * real_val + imag_val * imag_val) * scale_factor; + real_output[i] = (real_val < min_val) ? min_val : real_val; + } - // Clean up - fftw_destroy_plan(plan); - fftw_free(in); - fftw_free(out); + // Clean up + fftw_destroy_plan(plan); + fftw_free(in); + fftw_free(out); + + return real_output; + } +}; - return real_output; - } - }; } // namespace fft -#endif // FFT_H \ No newline at end of file +#endif // LIB_UTILS_FFT_H_ diff --git a/lib/utils/hanning.h b/lib/utils/hanning.h index 2f18ef2..96a92a3 100644 --- a/lib/utils/hanning.h +++ b/lib/utils/hanning.h @@ -1,2056 +1,348 @@ -#ifndef HANNING_H -#define HANNING_H +#ifndef LIB_UTILS_HANNING_H_ +#define LIB_UTILS_HANNING_H_ -constexpr double HANNIG_MATRIX[] = - { - 0.0000023508, - 0.0000094032, - 0.0000211571, - 0.0000376123, - 0.0000587689, - 0.0000846264, - 0.0001151848, - 0.0001504437, - 0.0001904028, - 0.0002350617, - 0.0002844199, - 0.0003384771, - 0.0003972327, - 0.0004606862, - 0.0005288369, - 0.0006016843, - 0.0006792276, - 0.0007614661, - 0.0008483991, - 0.0009400256, - 0.0010363449, - 0.0011373561, - 0.0012430582, - 0.0013534502, - 0.0014685311, - 0.0015882997, - 0.0017127550, - 0.0018418958, - 0.0019757209, - 0.0021142290, - 0.0022574189, - 0.0024052891, - 0.0025578382, - 0.0027150650, - 0.0028769677, - 0.0030435451, - 0.0032147954, - 0.0033907171, - 0.0035713085, - 0.0037565679, - 0.0039464936, - 0.0041410837, - 0.0043403366, - 0.0045442502, - 0.0047528227, - 0.0049660521, - 0.0051839364, - 0.0054064735, - 0.0056336614, - 0.0058654980, - 0.0061019809, - 0.0063431081, - 0.0065888773, - 0.0068392860, - 0.0070943321, - 0.0073540131, - 0.0076183265, - 0.0078872699, - 0.0081608407, - 0.0084390363, - 0.0087218542, - 0.0090092917, - 0.0093013461, - 0.0095980146, - 0.0098992944, - 0.0102051828, - 0.0105156768, - 0.0108307735, - 0.0111504700, - 0.0114747632, - 0.0118036501, - 0.0121371277, - 0.0124751927, - 0.0128178420, - 0.0131650723, - 0.0135168805, - 0.0138732631, - 0.0142342169, - 0.0145997385, - 0.0149698243, - 0.0153444710, - 0.0157236751, - 0.0161074328, - 0.0164957407, - 0.0168885951, - 0.0172859922, - 0.0176879285, - 0.0180944000, - 0.0185054029, - 0.0189209335, - 0.0193409877, - 0.0197655616, - 0.0201946513, - 0.0206282527, - 0.0210663617, - 0.0215089742, - 0.0219560861, - 0.0224076931, - 0.0228637910, - 0.0233243755, - 0.0237894423, - 0.0242589870, - 0.0247330052, - 0.0252114924, - 0.0256944441, - 0.0261818558, - 0.0266737229, - 0.0271700408, - 0.0276708049, - 0.0281760103, - 0.0286856523, - 0.0291997263, - 0.0297182272, - 0.0302411503, - 0.0307684907, - 0.0313002433, - 0.0318364032, - 0.0323769653, - 0.0329219246, - 0.0334712759, - 0.0340250141, - 0.0345831339, - 0.0351456301, - 0.0357124975, - 0.0362837306, - 0.0368593242, - 0.0374392727, - 0.0380235708, - 0.0386122130, - 0.0392051936, - 0.0398025073, - 0.0404041482, - 0.0410101108, - 0.0416203894, - 0.0422349782, - 0.0428538715, - 0.0434770634, - 0.0441045481, - 0.0447363196, - 0.0453723721, - 0.0460126996, - 0.0466572959, - 0.0473061552, - 0.0479592712, - 0.0486166378, - 0.0492782489, - 0.0499440982, - 0.0506141795, - 0.0512884865, - 0.0519670127, - 0.0526497519, - 0.0533366976, - 0.0540278434, - 0.0547231828, - 0.0554227092, - 0.0561264160, - 0.0568342966, - 0.0575463445, - 0.0582625528, - 0.0589829148, - 0.0597074238, - 0.0604360730, - 0.0611688555, - 0.0619057644, - 0.0626467928, - 0.0633919337, - 0.0641411801, - 0.0648945250, - 0.0656519612, - 0.0664134817, - 0.0671790793, - 0.0679487469, - 0.0687224770, - 0.0695002626, - 0.0702820963, - 0.0710679706, - 0.0718578783, - 0.0726518119, - 0.0734497639, - 0.0742517269, - 0.0750576933, - 0.0758676555, - 0.0766816058, - 0.0774995368, - 0.0783214406, - 0.0791473095, - 0.0799771357, - 0.0808109116, - 0.0816486291, - 0.0824902805, - 0.0833358578, - 0.0841853531, - 0.0850387583, - 0.0858960656, - 0.0867572667, - 0.0876223536, - 0.0884913182, - 0.0893641523, - 0.0902408477, - 0.0911213962, - 0.0920057894, - 0.0928940190, - 0.0937860768, - 0.0946819542, - 0.0955816430, - 0.0964851345, - 0.0973924204, - 0.0983034921, - 0.0992183410, - 0.1001369586, - 0.1010593361, - 0.1019854650, - 0.1029153364, - 0.1038489418, - 0.1047862722, - 0.1057273189, - 0.1066720730, - 0.1076205257, - 0.1085726679, - 0.1095284909, - 0.1104879855, - 0.1114511428, - 0.1124179537, - 0.1133884090, - 0.1143624998, - 0.1153402168, - 0.1163215508, - 0.1173064927, - 0.1182950331, - 0.1192871627, - 0.1202828722, - 0.1212821523, - 0.1222849936, - 0.1232913866, - 0.1243013218, - 0.1253147898, - 0.1263317811, - 0.1273522860, - 0.1283762950, - 0.1294037985, - 0.1304347867, - 0.1314692500, - 0.1325071788, - 0.1335485631, - 0.1345933932, - 0.1356416593, - 0.1366933516, - 0.1377484601, - 0.1388069749, - 0.1398688861, - 0.1409341836, - 0.1420028576, - 0.1430748978, - 0.1441502943, - 0.1452290369, - 0.1463111155, - 0.1473965199, - 0.1484852399, - 0.1495772653, - 0.1506725857, - 0.1517711910, - 0.1528730707, - 0.1539782145, - 0.1550866121, - 0.1561982529, - 0.1573131265, - 0.1584312225, - 0.1595525304, - 0.1606770395, - 0.1618047394, - 0.1629356193, - 0.1640696688, - 0.1652068770, - 0.1663472334, - 0.1674907272, - 0.1686373477, - 0.1697870840, - 0.1709399254, - 0.1720958610, - 0.1732548799, - 0.1744169713, - 0.1755821242, - 0.1767503277, - 0.1779215707, - 0.1790958423, - 0.1802731315, - 0.1814534271, - 0.1826367180, - 0.1838229932, - 0.1850122415, - 0.1862044516, - 0.1873996124, - 0.1885977127, - 0.1897987412, - 0.1910026865, - 0.1922095374, - 0.1934192825, - 0.1946319104, - 0.1958474098, - 0.1970657692, - 0.1982869772, - 0.1995110222, - 0.2007378927, - 0.2019675773, - 0.2032000643, - 0.2044353422, - 0.2056733994, - 0.2069142242, - 0.2081578049, - 0.2094041298, - 0.2106531873, - 0.2119049656, - 0.2131594529, - 0.2144166374, - 0.2156765073, - 0.2169390508, - 0.2182042559, - 0.2194721108, - 0.2207426036, - 0.2220157223, - 0.2232914549, - 0.2245697895, - 0.2258507140, - 0.2271342163, - 0.2284202845, - 0.2297089064, - 0.2310000699, - 0.2322937629, - 0.2335899731, - 0.2348886885, - 0.2361898967, - 0.2374935856, - 0.2387997429, - 0.2401083564, - 0.2414194136, - 0.2427329023, - 0.2440488102, - 0.2453671248, - 0.2466878338, - 0.2480109247, - 0.2493363851, - 0.2506642026, - 0.2519943646, - 0.2533268587, - 0.2546616722, - 0.2559987928, - 0.2573382077, - 0.2586799044, - 0.2600238703, - 0.2613700928, - 0.2627185591, - 0.2640692567, - 0.2654221727, - 0.2667772945, - 0.2681346094, - 0.2694941045, - 0.2708557672, - 0.2722195845, - 0.2735855437, - 0.2749536319, - 0.2763238362, - 0.2776961439, - 0.2790705418, - 0.2804470173, - 0.2818255572, - 0.2832061487, - 0.2845887787, - 0.2859734343, - 0.2873601024, - 0.2887487700, - 0.2901394241, - 0.2915320515, - 0.2929266392, - 0.2943231740, - 0.2957216428, - 0.2971220325, - 0.2985243300, - 0.2999285219, - 0.3013345951, - 0.3027425364, - 0.3041523326, - 0.3055639704, - 0.3069774365, - 0.3083927176, - 0.3098098005, - 0.3112286717, - 0.3126493180, - 0.3140717260, - 0.3154958823, - 0.3169217735, - 0.3183493863, - 0.3197787071, - 0.3212097227, - 0.3226424194, - 0.3240767838, - 0.3255128025, - 0.3269504619, - 0.3283897485, - 0.3298306489, - 0.3312731493, - 0.3327172363, - 0.3341628964, - 0.3356101158, - 0.3370588810, - 0.3385091784, - 0.3399609943, - 0.3414143150, - 0.3428691270, - 0.3443254166, - 0.3457831699, - 0.3472423734, - 0.3487030133, - 0.3501650759, - 0.3516285474, - 0.3530934141, - 0.3545596622, - 0.3560272778, - 0.3574962473, - 0.3589665568, - 0.3604381924, - 0.3619111404, - 0.3633853868, - 0.3648609179, - 0.3663377196, - 0.3678157783, - 0.3692950799, - 0.3707756105, - 0.3722573563, - 0.3737403032, - 0.3752244374, - 0.3767097449, - 0.3781962117, - 0.3796838239, - 0.3811725674, - 0.3826624282, - 0.3841533924, - 0.3856454460, - 0.3871385748, - 0.3886327649, - 0.3901280022, - 0.3916242727, - 0.3931215622, - 0.3946198567, - 0.3961191422, - 0.3976194044, - 0.3991206294, - 0.4006228029, - 0.4021259109, - 0.4036299393, - 0.4051348738, - 0.4066407004, - 0.4081474048, - 0.4096549729, - 0.4111633906, - 0.4126726436, - 0.4141827178, - 0.4156935990, - 0.4172052728, - 0.4187177253, - 0.4202309420, - 0.4217449088, - 0.4232596115, - 0.4247750358, - 0.4262911674, - 0.4278079921, - 0.4293254957, - 0.4308436638, - 0.4323624822, - 0.4338819366, - 0.4354020128, - 0.4369226964, - 0.4384439731, - 0.4399658286, - 0.4414882486, - 0.4430112189, - 0.4445347250, - 0.4460587526, - 0.4475832875, - 0.4491083153, - 0.4506338216, - 0.4521597921, - 0.4536862125, - 0.4552130684, - 0.4567403454, - 0.4582680291, - 0.4597961053, - 0.4613245596, - 0.4628533775, - 0.4643825447, - 0.4659120468, - 0.4674418695, - 0.4689719983, - 0.4705024189, - 0.4720331168, - 0.4735640778, - 0.4750952873, - 0.4766267310, - 0.4781583944, - 0.4796902633, - 0.4812223231, - 0.4827545595, - 0.4842869581, - 0.4858195044, - 0.4873521841, - 0.4888849827, - 0.4904178858, - 0.4919508790, - 0.4934839479, - 0.4950170780, - 0.4965502551, - 0.4980834645, - 0.4996166920, - 0.5011499231, - 0.5026831434, - 0.5042163384, - 0.5057494938, - 0.5072825951, - 0.5088156280, - 0.5103485780, - 0.5118814306, - 0.5134141715, - 0.5149467863, - 0.5164792606, - 0.5180115799, - 0.5195437298, - 0.5210756959, - 0.5226074639, - 0.5241390193, - 0.5256703477, - 0.5272014347, - 0.5287322659, - 0.5302628270, - 0.5317931035, - 0.5333230810, - 0.5348527452, - 0.5363820817, - 0.5379110760, - 0.5394397139, - 0.5409679809, - 0.5424958627, - 0.5440233449, - 0.5455504131, - 0.5470770530, - 0.5486032503, - 0.5501289905, - 0.5516542593, - 0.5531790424, - 0.5547033255, - 0.5562270942, - 0.5577503341, - 0.5592730311, - 0.5607951706, - 0.5623167385, - 0.5638377205, - 0.5653581021, - 0.5668778692, - 0.5683970074, - 0.5699155024, - 0.5714333401, - 0.5729505060, - 0.5744669860, - 0.5759827657, - 0.5774978309, - 0.5790121675, - 0.5805257610, - 0.5820385974, - 0.5835506623, - 0.5850619416, - 0.5865724210, - 0.5880820864, - 0.5895909235, - 0.5910989182, - 0.5926060563, - 0.5941123235, - 0.5956177058, - 0.5971221890, - 0.5986257590, - 0.6001284015, - 0.6016301025, - 0.6031308479, - 0.6046306235, - 0.6061294153, - 0.6076272091, - 0.6091239908, - 0.6106197465, - 0.6121144619, - 0.6136081231, - 0.6151007161, - 0.6165922267, - 0.6180826410, - 0.6195719449, - 0.6210601245, - 0.6225471657, - 0.6240330546, - 0.6255177772, - 0.6270013195, - 0.6284836676, - 0.6299648076, - 0.6314447254, - 0.6329234073, - 0.6344008392, - 0.6358770074, - 0.6373518979, - 0.6388254968, - 0.6402977903, - 0.6417687646, - 0.6432384058, - 0.6447067001, - 0.6461736337, - 0.6476391928, - 0.6491033636, - 0.6505661323, - 0.6520274853, - 0.6534874087, - 0.6549458889, - 0.6564029120, - 0.6578584645, - 0.6593125326, - 0.6607651027, - 0.6622161610, - 0.6636656940, - 0.6651136880, - 0.6665601294, - 0.6680050047, - 0.6694483001, - 0.6708900022, - 0.6723300973, - 0.6737685721, - 0.6752054128, - 0.6766406060, - 0.6780741383, - 0.6795059961, - 0.6809361660, - 0.6823646344, - 0.6837913881, - 0.6852164136, - 0.6866396974, - 0.6880612262, - 0.6894809866, - 0.6908989653, - 0.6923151490, - 0.6937295243, - 0.6951420779, - 0.6965527965, - 0.6979616669, - 0.6993686758, - 0.7007738101, - 0.7021770564, - 0.7035784016, - 0.7049778325, - 0.7063753360, - 0.7077708989, - 0.7091645081, - 0.7105561504, - 0.7119458129, - 0.7133334824, - 0.7147191459, - 0.7161027903, - 0.7174844027, - 0.7188639700, - 0.7202414793, - 0.7216169176, - 0.7229902721, - 0.7243615297, - 0.7257306776, - 0.7270977029, - 0.7284625927, - 0.7298253343, - 0.7311859148, - 0.7325443214, - 0.7339005413, - 0.7352545618, - 0.7366063702, - 0.7379559537, - 0.7393032997, - 0.7406483955, - 0.7419912284, - 0.7433317858, - 0.7446700551, - 0.7460060237, - 0.7473396791, - 0.7486710087, - 0.7500000000, - 0.7513266405, - 0.7526509177, - 0.7539728192, - 0.7552923326, - 0.7566094454, - 0.7579241452, - 0.7592364197, - 0.7605462566, - 0.7618536435, - 0.7631585681, - 0.7644610182, - 0.7657609816, - 0.7670584459, - 0.7683533990, - 0.7696458288, - 0.7709357230, - 0.7722230696, - 0.7735078563, - 0.7747900713, - 0.7760697023, - 0.7773467374, - 0.7786211646, - 0.7798929718, - 0.7811621471, - 0.7824286786, - 0.7836925544, - 0.7849537626, - 0.7862122913, - 0.7874681286, - 0.7887212629, - 0.7899716822, - 0.7912193749, - 0.7924643292, - 0.7937065334, - 0.7949459759, - 0.7961826448, - 0.7974165288, - 0.7986476160, - 0.7998758950, - 0.8011013543, - 0.8023239822, - 0.8035437673, - 0.8047606981, - 0.8059747632, - 0.8071859511, - 0.8083942505, - 0.8095996501, - 0.8108021384, - 0.8120017041, - 0.8131983361, - 0.8143920230, - 0.8155827536, - 0.8167705167, - 0.8179553012, - 0.8191370958, - 0.8203158896, - 0.8214916713, - 0.8226644301, - 0.8238341547, - 0.8250008343, - 0.8261644578, - 0.8273250143, - 0.8284824929, - 0.8296368828, - 0.8307881730, - 0.8319363527, - 0.8330814112, - 0.8342233376, - 0.8353621213, - 0.8364977515, - 0.8376302175, - 0.8387595088, - 0.8398856146, - 0.8410085244, - 0.8421282276, - 0.8432447138, - 0.8443579723, - 0.8454679928, - 0.8465747647, - 0.8476782778, - 0.8487785216, - 0.8498754857, - 0.8509691599, - 0.8520595339, - 0.8531465974, - 0.8542303401, - 0.8553107520, - 0.8563878228, - 0.8574615425, - 0.8585319008, - 0.8595988878, - 0.8606624934, - 0.8617227077, - 0.8627795206, - 0.8638329222, - 0.8648829026, - 0.8659294520, - 0.8669725604, - 0.8680122182, - 0.8690484154, - 0.8700811424, - 0.8711103895, - 0.8721361469, - 0.8731584051, - 0.8741771544, - 0.8751923852, - 0.8762040880, - 0.8772122533, - 0.8782168716, - 0.8792179335, - 0.8802154295, - 0.8812093502, - 0.8821996864, - 0.8831864286, - 0.8841695677, - 0.8851490944, - 0.8861249994, - 0.8870972736, - 0.8880659079, - 0.8890308931, - 0.8899922202, - 0.8909498801, - 0.8919038639, - 0.8928541624, - 0.8938007669, - 0.8947436684, - 0.8956828581, - 0.8966183271, - 0.8975500666, - 0.8984780678, - 0.8994023221, - 0.9003228207, - 0.9012395551, - 0.9021525164, - 0.9030616963, - 0.9039670861, - 0.9048686773, - 0.9057664615, - 0.9066604301, - 0.9075505748, - 0.9084368873, - 0.9093193592, - 0.9101979821, - 0.9110727479, - 0.9119436483, - 0.9128106750, - 0.9136738201, - 0.9145330753, - 0.9153884325, - 0.9162398838, - 0.9170874211, - 0.9179310364, - 0.9187707219, - 0.9196064696, - 0.9204382716, - 0.9212661201, - 0.9220900075, - 0.9229099258, - 0.9237258674, - 0.9245378246, - 0.9253457899, - 0.9261497555, - 0.9269497139, - 0.9277456577, - 0.9285375792, - 0.9293254712, - 0.9301093261, - 0.9308891366, - 0.9316648954, - 0.9324365952, - 0.9332042287, - 0.9339677886, - 0.9347272679, - 0.9354826594, - 0.9362339559, - 0.9369811504, - 0.9377242359, - 0.9384632054, - 0.9391980520, - 0.9399287687, - 0.9406553486, - 0.9413777850, - 0.9420960710, - 0.9428101999, - 0.9435201650, - 0.9442259596, - 0.9449275770, - 0.9456250107, - 0.9463182541, - 0.9470073006, - 0.9476921439, - 0.9483727774, - 0.9490491948, - 0.9497213897, - 0.9503893558, - 0.9510530868, - 0.9517125764, - 0.9523678185, - 0.9530188069, - 0.9536655355, - 0.9543079981, - 0.9549461889, - 0.9555801016, - 0.9562097305, - 0.9568350695, - 0.9574561128, - 0.9580728546, - 0.9586852890, - 0.9592934103, - 0.9598972128, - 0.9604966908, - 0.9610918387, - 0.9616826508, - 0.9622691216, - 0.9628512456, - 0.9634290173, - 0.9640024313, - 0.9645714822, - 0.9651361647, - 0.9656964734, - 0.9662524030, - 0.9668039484, - 0.9673511043, - 0.9678938657, - 0.9684322273, - 0.9689661842, - 0.9694957313, - 0.9700208637, - 0.9705415763, - 0.9710578644, - 0.9715697230, - 0.9720771473, - 0.9725801326, - 0.9730786742, - 0.9735727673, - 0.9740624073, - 0.9745475895, - 0.9750283096, - 0.9755045628, - 0.9759763448, - 0.9764436511, - 0.9769064773, - 0.9773648190, - 0.9778186720, - 0.9782680320, - 0.9787128947, - 0.9791532560, - 0.9795891117, - 0.9800204578, - 0.9804472901, - 0.9808696047, - 0.9812873975, - 0.9817006648, - 0.9821094025, - 0.9825136068, - 0.9829132740, - 0.9833084002, - 0.9836989818, - 0.9840850151, - 0.9844664964, - 0.9848434222, - 0.9852157889, - 0.9855835931, - 0.9859468312, - 0.9863054998, - 0.9866595956, - 0.9870091153, - 0.9873540555, - 0.9876944131, - 0.9880301847, - 0.9883613673, - 0.9886879578, - 0.9890099530, - 0.9893273500, - 0.9896401457, - 0.9899483373, - 0.9902519217, - 0.9905508963, - 0.9908452580, - 0.9911350043, - 0.9914201323, - 0.9917006395, - 0.9919765230, - 0.9922477804, - 0.9925144091, - 0.9927764066, - 0.9930337704, - 0.9932864982, - 0.9935345874, - 0.9937780359, - 0.9940168412, - 0.9942510013, - 0.9944805137, - 0.9947053765, - 0.9949255875, - 0.9951411446, - 0.9953520458, - 0.9955582891, - 0.9957598726, - 0.9959567943, - 0.9961490524, - 0.9963366452, - 0.9965195708, - 0.9966978276, - 0.9968714138, - 0.9970403278, - 0.9972045681, - 0.9973641330, - 0.9975190211, - 0.9976692310, - 0.9978147612, - 0.9979556103, - 0.9980917771, - 0.9982232602, - 0.9983500584, - 0.9984721705, - 0.9985895954, - 0.9987023320, - 0.9988103791, - 0.9989137359, - 0.9990124013, - 0.9991063743, - 0.9991956542, - 0.9992802400, - 0.9993601310, - 0.9994353264, - 0.9995058256, - 0.9995716277, - 0.9996327323, - 0.9996891388, - 0.9997408466, - 0.9997878552, - 0.9998301643, - 0.9998677733, - 0.9999006820, - 0.9999288900, - 0.9999523970, - 0.9999712030, - 0.9999853076, - 0.9999947107, - 0.9999994123, - 0.9999994123, - 0.9999947107, - 0.9999853076, - 0.9999712030, - 0.9999523970, - 0.9999288900, - 0.9999006820, - 0.9998677733, - 0.9998301643, - 0.9997878552, - 0.9997408466, - 0.9996891388, - 0.9996327323, - 0.9995716277, - 0.9995058256, - 0.9994353264, - 0.9993601310, - 0.9992802400, - 0.9991956542, - 0.9991063743, - 0.9990124013, - 0.9989137359, - 0.9988103791, - 0.9987023320, - 0.9985895954, - 0.9984721705, - 0.9983500584, - 0.9982232602, - 0.9980917771, - 0.9979556103, - 0.9978147612, - 0.9976692310, - 0.9975190211, - 0.9973641330, - 0.9972045681, - 0.9970403278, - 0.9968714138, - 0.9966978276, - 0.9965195708, - 0.9963366452, - 0.9961490524, - 0.9959567943, - 0.9957598726, - 0.9955582891, - 0.9953520458, - 0.9951411446, - 0.9949255875, - 0.9947053765, - 0.9944805137, - 0.9942510013, - 0.9940168412, - 0.9937780359, - 0.9935345874, - 0.9932864982, - 0.9930337704, - 0.9927764066, - 0.9925144091, - 0.9922477804, - 0.9919765230, - 0.9917006395, - 0.9914201323, - 0.9911350043, - 0.9908452580, - 0.9905508963, - 0.9902519217, - 0.9899483373, - 0.9896401457, - 0.9893273500, - 0.9890099530, - 0.9886879578, - 0.9883613673, - 0.9880301847, - 0.9876944131, - 0.9873540555, - 0.9870091153, - 0.9866595956, - 0.9863054998, - 0.9859468312, - 0.9855835931, - 0.9852157889, - 0.9848434222, - 0.9844664964, - 0.9840850151, - 0.9836989818, - 0.9833084002, - 0.9829132740, - 0.9825136068, - 0.9821094025, - 0.9817006648, - 0.9812873975, - 0.9808696047, - 0.9804472901, - 0.9800204578, - 0.9795891117, - 0.9791532560, - 0.9787128947, - 0.9782680320, - 0.9778186720, - 0.9773648190, - 0.9769064773, - 0.9764436511, - 0.9759763448, - 0.9755045628, - 0.9750283096, - 0.9745475895, - 0.9740624073, - 0.9735727673, - 0.9730786742, - 0.9725801326, - 0.9720771473, - 0.9715697230, - 0.9710578644, - 0.9705415763, - 0.9700208637, - 0.9694957313, - 0.9689661842, - 0.9684322273, - 0.9678938657, - 0.9673511043, - 0.9668039484, - 0.9662524030, - 0.9656964734, - 0.9651361647, - 0.9645714822, - 0.9640024313, - 0.9634290173, - 0.9628512456, - 0.9622691216, - 0.9616826508, - 0.9610918387, - 0.9604966908, - 0.9598972128, - 0.9592934103, - 0.9586852890, - 0.9580728546, - 0.9574561128, - 0.9568350695, - 0.9562097305, - 0.9555801016, - 0.9549461889, - 0.9543079981, - 0.9536655355, - 0.9530188069, - 0.9523678185, - 0.9517125764, - 0.9510530868, - 0.9503893558, - 0.9497213897, - 0.9490491948, - 0.9483727774, - 0.9476921439, - 0.9470073006, - 0.9463182541, - 0.9456250107, - 0.9449275770, - 0.9442259596, - 0.9435201650, - 0.9428101999, - 0.9420960710, - 0.9413777850, - 0.9406553486, - 0.9399287687, - 0.9391980520, - 0.9384632054, - 0.9377242359, - 0.9369811504, - 0.9362339559, - 0.9354826594, - 0.9347272679, - 0.9339677886, - 0.9332042287, - 0.9324365952, - 0.9316648954, - 0.9308891366, - 0.9301093261, - 0.9293254712, - 0.9285375792, - 0.9277456577, - 0.9269497139, - 0.9261497555, - 0.9253457899, - 0.9245378246, - 0.9237258674, - 0.9229099258, - 0.9220900075, - 0.9212661201, - 0.9204382716, - 0.9196064696, - 0.9187707219, - 0.9179310364, - 0.9170874211, - 0.9162398838, - 0.9153884325, - 0.9145330753, - 0.9136738201, - 0.9128106750, - 0.9119436483, - 0.9110727479, - 0.9101979821, - 0.9093193592, - 0.9084368873, - 0.9075505748, - 0.9066604301, - 0.9057664615, - 0.9048686773, - 0.9039670861, - 0.9030616963, - 0.9021525164, - 0.9012395551, - 0.9003228207, - 0.8994023221, - 0.8984780678, - 0.8975500666, - 0.8966183271, - 0.8956828581, - 0.8947436684, - 0.8938007669, - 0.8928541624, - 0.8919038639, - 0.8909498801, - 0.8899922202, - 0.8890308931, - 0.8880659079, - 0.8870972736, - 0.8861249994, - 0.8851490944, - 0.8841695677, - 0.8831864286, - 0.8821996864, - 0.8812093502, - 0.8802154295, - 0.8792179335, - 0.8782168716, - 0.8772122533, - 0.8762040880, - 0.8751923852, - 0.8741771544, - 0.8731584051, - 0.8721361469, - 0.8711103895, - 0.8700811424, - 0.8690484154, - 0.8680122182, - 0.8669725604, - 0.8659294520, - 0.8648829026, - 0.8638329222, - 0.8627795206, - 0.8617227077, - 0.8606624934, - 0.8595988878, - 0.8585319008, - 0.8574615425, - 0.8563878228, - 0.8553107520, - 0.8542303401, - 0.8531465974, - 0.8520595339, - 0.8509691599, - 0.8498754857, - 0.8487785216, - 0.8476782778, - 0.8465747647, - 0.8454679928, - 0.8443579723, - 0.8432447138, - 0.8421282276, - 0.8410085244, - 0.8398856146, - 0.8387595088, - 0.8376302175, - 0.8364977515, - 0.8353621213, - 0.8342233376, - 0.8330814112, - 0.8319363527, - 0.8307881730, - 0.8296368828, - 0.8284824929, - 0.8273250143, - 0.8261644578, - 0.8250008343, - 0.8238341547, - 0.8226644301, - 0.8214916713, - 0.8203158896, - 0.8191370958, - 0.8179553012, - 0.8167705167, - 0.8155827536, - 0.8143920230, - 0.8131983361, - 0.8120017041, - 0.8108021384, - 0.8095996501, - 0.8083942505, - 0.8071859511, - 0.8059747632, - 0.8047606981, - 0.8035437673, - 0.8023239822, - 0.8011013543, - 0.7998758950, - 0.7986476160, - 0.7974165288, - 0.7961826448, - 0.7949459759, - 0.7937065334, - 0.7924643292, - 0.7912193749, - 0.7899716822, - 0.7887212629, - 0.7874681286, - 0.7862122913, - 0.7849537626, - 0.7836925544, - 0.7824286786, - 0.7811621471, - 0.7798929718, - 0.7786211646, - 0.7773467374, - 0.7760697023, - 0.7747900713, - 0.7735078563, - 0.7722230696, - 0.7709357230, - 0.7696458288, - 0.7683533990, - 0.7670584459, - 0.7657609816, - 0.7644610182, - 0.7631585681, - 0.7618536435, - 0.7605462566, - 0.7592364197, - 0.7579241452, - 0.7566094454, - 0.7552923326, - 0.7539728192, - 0.7526509177, - 0.7513266405, - 0.7500000000, - 0.7486710087, - 0.7473396791, - 0.7460060237, - 0.7446700551, - 0.7433317858, - 0.7419912284, - 0.7406483955, - 0.7393032997, - 0.7379559537, - 0.7366063702, - 0.7352545618, - 0.7339005413, - 0.7325443214, - 0.7311859148, - 0.7298253343, - 0.7284625927, - 0.7270977029, - 0.7257306776, - 0.7243615297, - 0.7229902721, - 0.7216169176, - 0.7202414793, - 0.7188639700, - 0.7174844027, - 0.7161027903, - 0.7147191459, - 0.7133334824, - 0.7119458129, - 0.7105561504, - 0.7091645081, - 0.7077708989, - 0.7063753360, - 0.7049778325, - 0.7035784016, - 0.7021770564, - 0.7007738101, - 0.6993686758, - 0.6979616669, - 0.6965527965, - 0.6951420779, - 0.6937295243, - 0.6923151490, - 0.6908989653, - 0.6894809866, - 0.6880612262, - 0.6866396974, - 0.6852164136, - 0.6837913881, - 0.6823646344, - 0.6809361660, - 0.6795059961, - 0.6780741383, - 0.6766406060, - 0.6752054128, - 0.6737685721, - 0.6723300973, - 0.6708900022, - 0.6694483001, - 0.6680050047, - 0.6665601294, - 0.6651136880, - 0.6636656940, - 0.6622161610, - 0.6607651027, - 0.6593125326, - 0.6578584645, - 0.6564029120, - 0.6549458889, - 0.6534874087, - 0.6520274853, - 0.6505661323, - 0.6491033636, - 0.6476391928, - 0.6461736337, - 0.6447067001, - 0.6432384058, - 0.6417687646, - 0.6402977903, - 0.6388254968, - 0.6373518979, - 0.6358770074, - 0.6344008392, - 0.6329234073, - 0.6314447254, - 0.6299648076, - 0.6284836676, - 0.6270013195, - 0.6255177772, - 0.6240330546, - 0.6225471657, - 0.6210601245, - 0.6195719449, - 0.6180826410, - 0.6165922267, - 0.6151007161, - 0.6136081231, - 0.6121144619, - 0.6106197465, - 0.6091239908, - 0.6076272091, - 0.6061294153, - 0.6046306235, - 0.6031308479, - 0.6016301025, - 0.6001284015, - 0.5986257590, - 0.5971221890, - 0.5956177058, - 0.5941123235, - 0.5926060563, - 0.5910989182, - 0.5895909235, - 0.5880820864, - 0.5865724210, - 0.5850619416, - 0.5835506623, - 0.5820385974, - 0.5805257610, - 0.5790121675, - 0.5774978309, - 0.5759827657, - 0.5744669860, - 0.5729505060, - 0.5714333401, - 0.5699155024, - 0.5683970074, - 0.5668778692, - 0.5653581021, - 0.5638377205, - 0.5623167385, - 0.5607951706, - 0.5592730311, - 0.5577503341, - 0.5562270942, - 0.5547033255, - 0.5531790424, - 0.5516542593, - 0.5501289905, - 0.5486032503, - 0.5470770530, - 0.5455504131, - 0.5440233449, - 0.5424958627, - 0.5409679809, - 0.5394397139, - 0.5379110760, - 0.5363820817, - 0.5348527452, - 0.5333230810, - 0.5317931035, - 0.5302628270, - 0.5287322659, - 0.5272014347, - 0.5256703477, - 0.5241390193, - 0.5226074639, - 0.5210756959, - 0.5195437298, - 0.5180115799, - 0.5164792606, - 0.5149467863, - 0.5134141715, - 0.5118814306, - 0.5103485780, - 0.5088156280, - 0.5072825951, - 0.5057494938, - 0.5042163384, - 0.5026831434, - 0.5011499231, - 0.4996166920, - 0.4980834645, - 0.4965502551, - 0.4950170780, - 0.4934839479, - 0.4919508790, - 0.4904178858, - 0.4888849827, - 0.4873521841, - 0.4858195044, - 0.4842869581, - 0.4827545595, - 0.4812223231, - 0.4796902633, - 0.4781583944, - 0.4766267310, - 0.4750952873, - 0.4735640778, - 0.4720331168, - 0.4705024189, - 0.4689719983, - 0.4674418695, - 0.4659120468, - 0.4643825447, - 0.4628533775, - 0.4613245596, - 0.4597961053, - 0.4582680291, - 0.4567403454, - 0.4552130684, - 0.4536862125, - 0.4521597921, - 0.4506338216, - 0.4491083153, - 0.4475832875, - 0.4460587526, - 0.4445347250, - 0.4430112189, - 0.4414882486, - 0.4399658286, - 0.4384439731, - 0.4369226964, - 0.4354020128, - 0.4338819366, - 0.4323624822, - 0.4308436638, - 0.4293254957, - 0.4278079921, - 0.4262911674, - 0.4247750358, - 0.4232596115, - 0.4217449088, - 0.4202309420, - 0.4187177253, - 0.4172052728, - 0.4156935990, - 0.4141827178, - 0.4126726436, - 0.4111633906, - 0.4096549729, - 0.4081474048, - 0.4066407004, - 0.4051348738, - 0.4036299393, - 0.4021259109, - 0.4006228029, - 0.3991206294, - 0.3976194044, - 0.3961191422, - 0.3946198567, - 0.3931215622, - 0.3916242727, - 0.3901280022, - 0.3886327649, - 0.3871385748, - 0.3856454460, - 0.3841533924, - 0.3826624282, - 0.3811725674, - 0.3796838239, - 0.3781962117, - 0.3767097449, - 0.3752244374, - 0.3737403032, - 0.3722573563, - 0.3707756105, - 0.3692950799, - 0.3678157783, - 0.3663377196, - 0.3648609179, - 0.3633853868, - 0.3619111404, - 0.3604381924, - 0.3589665568, - 0.3574962473, - 0.3560272778, - 0.3545596622, - 0.3530934141, - 0.3516285474, - 0.3501650759, - 0.3487030133, - 0.3472423734, - 0.3457831699, - 0.3443254166, - 0.3428691270, - 0.3414143150, - 0.3399609943, - 0.3385091784, - 0.3370588810, - 0.3356101158, - 0.3341628964, - 0.3327172363, - 0.3312731493, - 0.3298306489, - 0.3283897485, - 0.3269504619, - 0.3255128025, - 0.3240767838, - 0.3226424194, - 0.3212097227, - 0.3197787071, - 0.3183493863, - 0.3169217735, - 0.3154958823, - 0.3140717260, - 0.3126493180, - 0.3112286717, - 0.3098098005, - 0.3083927176, - 0.3069774365, - 0.3055639704, - 0.3041523326, - 0.3027425364, - 0.3013345951, - 0.2999285219, - 0.2985243300, - 0.2971220325, - 0.2957216428, - 0.2943231740, - 0.2929266392, - 0.2915320515, - 0.2901394241, - 0.2887487700, - 0.2873601024, - 0.2859734343, - 0.2845887787, - 0.2832061487, - 0.2818255572, - 0.2804470173, - 0.2790705418, - 0.2776961439, - 0.2763238362, - 0.2749536319, - 0.2735855437, - 0.2722195845, - 0.2708557672, - 0.2694941045, - 0.2681346094, - 0.2667772945, - 0.2654221727, - 0.2640692567, - 0.2627185591, - 0.2613700928, - 0.2600238703, - 0.2586799044, - 0.2573382077, - 0.2559987928, - 0.2546616722, - 0.2533268587, - 0.2519943646, - 0.2506642026, - 0.2493363851, - 0.2480109247, - 0.2466878338, - 0.2453671248, - 0.2440488102, - 0.2427329023, - 0.2414194136, - 0.2401083564, - 0.2387997429, - 0.2374935856, - 0.2361898967, - 0.2348886885, - 0.2335899731, - 0.2322937629, - 0.2310000699, - 0.2297089064, - 0.2284202845, - 0.2271342163, - 0.2258507140, - 0.2245697895, - 0.2232914549, - 0.2220157223, - 0.2207426036, - 0.2194721108, - 0.2182042559, - 0.2169390508, - 0.2156765073, - 0.2144166374, - 0.2131594529, - 0.2119049656, - 0.2106531873, - 0.2094041298, - 0.2081578049, - 0.2069142242, - 0.2056733994, - 0.2044353422, - 0.2032000643, - 0.2019675773, - 0.2007378927, - 0.1995110222, - 0.1982869772, - 0.1970657692, - 0.1958474098, - 0.1946319104, - 0.1934192825, - 0.1922095374, - 0.1910026865, - 0.1897987412, - 0.1885977127, - 0.1873996124, - 0.1862044516, - 0.1850122415, - 0.1838229932, - 0.1826367180, - 0.1814534271, - 0.1802731315, - 0.1790958423, - 0.1779215707, - 0.1767503277, - 0.1755821242, - 0.1744169713, - 0.1732548799, - 0.1720958610, - 0.1709399254, - 0.1697870840, - 0.1686373477, - 0.1674907272, - 0.1663472334, - 0.1652068770, - 0.1640696688, - 0.1629356193, - 0.1618047394, - 0.1606770395, - 0.1595525304, - 0.1584312225, - 0.1573131265, - 0.1561982529, - 0.1550866121, - 0.1539782145, - 0.1528730707, - 0.1517711910, - 0.1506725857, - 0.1495772653, - 0.1484852399, - 0.1473965199, - 0.1463111155, - 0.1452290369, - 0.1441502943, - 0.1430748978, - 0.1420028576, - 0.1409341836, - 0.1398688861, - 0.1388069749, - 0.1377484601, - 0.1366933516, - 0.1356416593, - 0.1345933932, - 0.1335485631, - 0.1325071788, - 0.1314692500, - 0.1304347867, - 0.1294037985, - 0.1283762950, - 0.1273522860, - 0.1263317811, - 0.1253147898, - 0.1243013218, - 0.1232913866, - 0.1222849936, - 0.1212821523, - 0.1202828722, - 0.1192871627, - 0.1182950331, - 0.1173064927, - 0.1163215508, - 0.1153402168, - 0.1143624998, - 0.1133884090, - 0.1124179537, - 0.1114511428, - 0.1104879855, - 0.1095284909, - 0.1085726679, - 0.1076205257, - 0.1066720730, - 0.1057273189, - 0.1047862722, - 0.1038489418, - 0.1029153364, - 0.1019854650, - 0.1010593361, - 0.1001369586, - 0.0992183410, - 0.0983034921, - 0.0973924204, - 0.0964851345, - 0.0955816430, - 0.0946819542, - 0.0937860768, - 0.0928940190, - 0.0920057894, - 0.0911213962, - 0.0902408477, - 0.0893641523, - 0.0884913182, - 0.0876223536, - 0.0867572667, - 0.0858960656, - 0.0850387583, - 0.0841853531, - 0.0833358578, - 0.0824902805, - 0.0816486291, - 0.0808109116, - 0.0799771357, - 0.0791473095, - 0.0783214406, - 0.0774995368, - 0.0766816058, - 0.0758676555, - 0.0750576933, - 0.0742517269, - 0.0734497639, - 0.0726518119, - 0.0718578783, - 0.0710679706, - 0.0702820963, - 0.0695002626, - 0.0687224770, - 0.0679487469, - 0.0671790793, - 0.0664134817, - 0.0656519612, - 0.0648945250, - 0.0641411801, - 0.0633919337, - 0.0626467928, - 0.0619057644, - 0.0611688555, - 0.0604360730, - 0.0597074238, - 0.0589829148, - 0.0582625528, - 0.0575463445, - 0.0568342966, - 0.0561264160, - 0.0554227092, - 0.0547231828, - 0.0540278434, - 0.0533366976, - 0.0526497519, - 0.0519670127, - 0.0512884865, - 0.0506141795, - 0.0499440982, - 0.0492782489, - 0.0486166378, - 0.0479592712, - 0.0473061552, - 0.0466572959, - 0.0460126996, - 0.0453723721, - 0.0447363196, - 0.0441045481, - 0.0434770634, - 0.0428538715, - 0.0422349782, - 0.0416203894, - 0.0410101108, - 0.0404041482, - 0.0398025073, - 0.0392051936, - 0.0386122130, - 0.0380235708, - 0.0374392727, - 0.0368593242, - 0.0362837306, - 0.0357124975, - 0.0351456301, - 0.0345831339, - 0.0340250141, - 0.0334712759, - 0.0329219246, - 0.0323769653, - 0.0318364032, - 0.0313002433, - 0.0307684907, - 0.0302411503, - 0.0297182272, - 0.0291997263, - 0.0286856523, - 0.0281760103, - 0.0276708049, - 0.0271700408, - 0.0266737229, - 0.0261818558, - 0.0256944441, - 0.0252114924, - 0.0247330052, - 0.0242589870, - 0.0237894423, - 0.0233243755, - 0.0228637910, - 0.0224076931, - 0.0219560861, - 0.0215089742, - 0.0210663617, - 0.0206282527, - 0.0201946513, - 0.0197655616, - 0.0193409877, - 0.0189209335, - 0.0185054029, - 0.0180944000, - 0.0176879285, - 0.0172859922, - 0.0168885951, - 0.0164957407, - 0.0161074328, - 0.0157236751, - 0.0153444710, - 0.0149698243, - 0.0145997385, - 0.0142342169, - 0.0138732631, - 0.0135168805, - 0.0131650723, - 0.0128178420, - 0.0124751927, - 0.0121371277, - 0.0118036501, - 0.0114747632, - 0.0111504700, - 0.0108307735, - 0.0105156768, - 0.0102051828, - 0.0098992944, - 0.0095980146, - 0.0093013461, - 0.0090092917, - 0.0087218542, - 0.0084390363, - 0.0081608407, - 0.0078872699, - 0.0076183265, - 0.0073540131, - 0.0070943321, - 0.0068392860, - 0.0065888773, - 0.0063431081, - 0.0061019809, - 0.0058654980, - 0.0056336614, - 0.0054064735, - 0.0051839364, - 0.0049660521, - 0.0047528227, - 0.0045442502, - 0.0043403366, - 0.0041410837, - 0.0039464936, - 0.0037565679, - 0.0035713085, - 0.0033907171, - 0.0032147954, - 0.0030435451, - 0.0028769677, - 0.0027150650, - 0.0025578382, - 0.0024052891, - 0.0022574189, - 0.0021142290, - 0.0019757209, - 0.0018418958, - 0.0017127550, - 0.0015882997, - 0.0014685311, - 0.0013534502, - 0.0012430582, - 0.0011373561, - 0.0010363449, - 0.0009400256, - 0.0008483991, - 0.0007614661, - 0.0006792276, - 0.0006016843, - 0.0005288369, - 0.0004606862, - 0.0003972327, - 0.0003384771, - 0.0002844199, - 0.0002350617, - 0.0001904028, - 0.0001504437, - 0.0001151848, - 0.0000846264, - 0.0000587689, - 0.0000376123, - 0.0000211571, - 0.0000094032, - 0.0000023508 -}; +constexpr double HANNIG_MATRIX[] = { + 0.0000023508, 0.0000094032, 0.0000211571, 0.0000376123, 0.0000587689, 0.0000846264, + 0.0001151848, 0.0001504437, 0.0001904028, 0.0002350617, 0.0002844199, 0.0003384771, + 0.0003972327, 0.0004606862, 0.0005288369, 0.0006016843, 0.0006792276, 0.0007614661, + 0.0008483991, 0.0009400256, 0.0010363449, 0.0011373561, 0.0012430582, 0.0013534502, + 0.0014685311, 0.0015882997, 0.0017127550, 0.0018418958, 0.0019757209, 0.0021142290, + 0.0022574189, 0.0024052891, 0.0025578382, 0.0027150650, 0.0028769677, 0.0030435451, + 0.0032147954, 0.0033907171, 0.0035713085, 0.0037565679, 0.0039464936, 0.0041410837, + 0.0043403366, 0.0045442502, 0.0047528227, 0.0049660521, 0.0051839364, 0.0054064735, + 0.0056336614, 0.0058654980, 0.0061019809, 0.0063431081, 0.0065888773, 0.0068392860, + 0.0070943321, 0.0073540131, 0.0076183265, 0.0078872699, 0.0081608407, 0.0084390363, + 0.0087218542, 0.0090092917, 0.0093013461, 0.0095980146, 0.0098992944, 0.0102051828, + 0.0105156768, 0.0108307735, 0.0111504700, 0.0114747632, 0.0118036501, 0.0121371277, + 0.0124751927, 0.0128178420, 0.0131650723, 0.0135168805, 0.0138732631, 0.0142342169, + 0.0145997385, 0.0149698243, 0.0153444710, 0.0157236751, 0.0161074328, 0.0164957407, + 0.0168885951, 0.0172859922, 0.0176879285, 0.0180944000, 0.0185054029, 0.0189209335, + 0.0193409877, 0.0197655616, 0.0201946513, 0.0206282527, 0.0210663617, 0.0215089742, + 0.0219560861, 0.0224076931, 0.0228637910, 0.0233243755, 0.0237894423, 0.0242589870, + 0.0247330052, 0.0252114924, 0.0256944441, 0.0261818558, 0.0266737229, 0.0271700408, + 0.0276708049, 0.0281760103, 0.0286856523, 0.0291997263, 0.0297182272, 0.0302411503, + 0.0307684907, 0.0313002433, 0.0318364032, 0.0323769653, 0.0329219246, 0.0334712759, + 0.0340250141, 0.0345831339, 0.0351456301, 0.0357124975, 0.0362837306, 0.0368593242, + 0.0374392727, 0.0380235708, 0.0386122130, 0.0392051936, 0.0398025073, 0.0404041482, + 0.0410101108, 0.0416203894, 0.0422349782, 0.0428538715, 0.0434770634, 0.0441045481, + 0.0447363196, 0.0453723721, 0.0460126996, 0.0466572959, 0.0473061552, 0.0479592712, + 0.0486166378, 0.0492782489, 0.0499440982, 0.0506141795, 0.0512884865, 0.0519670127, + 0.0526497519, 0.0533366976, 0.0540278434, 0.0547231828, 0.0554227092, 0.0561264160, + 0.0568342966, 0.0575463445, 0.0582625528, 0.0589829148, 0.0597074238, 0.0604360730, + 0.0611688555, 0.0619057644, 0.0626467928, 0.0633919337, 0.0641411801, 0.0648945250, + 0.0656519612, 0.0664134817, 0.0671790793, 0.0679487469, 0.0687224770, 0.0695002626, + 0.0702820963, 0.0710679706, 0.0718578783, 0.0726518119, 0.0734497639, 0.0742517269, + 0.0750576933, 0.0758676555, 0.0766816058, 0.0774995368, 0.0783214406, 0.0791473095, + 0.0799771357, 0.0808109116, 0.0816486291, 0.0824902805, 0.0833358578, 0.0841853531, + 0.0850387583, 0.0858960656, 0.0867572667, 0.0876223536, 0.0884913182, 0.0893641523, + 0.0902408477, 0.0911213962, 0.0920057894, 0.0928940190, 0.0937860768, 0.0946819542, + 0.0955816430, 0.0964851345, 0.0973924204, 0.0983034921, 0.0992183410, 0.1001369586, + 0.1010593361, 0.1019854650, 0.1029153364, 0.1038489418, 0.1047862722, 0.1057273189, + 0.1066720730, 0.1076205257, 0.1085726679, 0.1095284909, 0.1104879855, 0.1114511428, + 0.1124179537, 0.1133884090, 0.1143624998, 0.1153402168, 0.1163215508, 0.1173064927, + 0.1182950331, 0.1192871627, 0.1202828722, 0.1212821523, 0.1222849936, 0.1232913866, + 0.1243013218, 0.1253147898, 0.1263317811, 0.1273522860, 0.1283762950, 0.1294037985, + 0.1304347867, 0.1314692500, 0.1325071788, 0.1335485631, 0.1345933932, 0.1356416593, + 0.1366933516, 0.1377484601, 0.1388069749, 0.1398688861, 0.1409341836, 0.1420028576, + 0.1430748978, 0.1441502943, 0.1452290369, 0.1463111155, 0.1473965199, 0.1484852399, + 0.1495772653, 0.1506725857, 0.1517711910, 0.1528730707, 0.1539782145, 0.1550866121, + 0.1561982529, 0.1573131265, 0.1584312225, 0.1595525304, 0.1606770395, 0.1618047394, + 0.1629356193, 0.1640696688, 0.1652068770, 0.1663472334, 0.1674907272, 0.1686373477, + 0.1697870840, 0.1709399254, 0.1720958610, 0.1732548799, 0.1744169713, 0.1755821242, + 0.1767503277, 0.1779215707, 0.1790958423, 0.1802731315, 0.1814534271, 0.1826367180, + 0.1838229932, 0.1850122415, 0.1862044516, 0.1873996124, 0.1885977127, 0.1897987412, + 0.1910026865, 0.1922095374, 0.1934192825, 0.1946319104, 0.1958474098, 0.1970657692, + 0.1982869772, 0.1995110222, 0.2007378927, 0.2019675773, 0.2032000643, 0.2044353422, + 0.2056733994, 0.2069142242, 0.2081578049, 0.2094041298, 0.2106531873, 0.2119049656, + 0.2131594529, 0.2144166374, 0.2156765073, 0.2169390508, 0.2182042559, 0.2194721108, + 0.2207426036, 0.2220157223, 0.2232914549, 0.2245697895, 0.2258507140, 0.2271342163, + 0.2284202845, 0.2297089064, 0.2310000699, 0.2322937629, 0.2335899731, 0.2348886885, + 0.2361898967, 0.2374935856, 0.2387997429, 0.2401083564, 0.2414194136, 0.2427329023, + 0.2440488102, 0.2453671248, 0.2466878338, 0.2480109247, 0.2493363851, 0.2506642026, + 0.2519943646, 0.2533268587, 0.2546616722, 0.2559987928, 0.2573382077, 0.2586799044, + 0.2600238703, 0.2613700928, 0.2627185591, 0.2640692567, 0.2654221727, 0.2667772945, + 0.2681346094, 0.2694941045, 0.2708557672, 0.2722195845, 0.2735855437, 0.2749536319, + 0.2763238362, 0.2776961439, 0.2790705418, 0.2804470173, 0.2818255572, 0.2832061487, + 0.2845887787, 0.2859734343, 0.2873601024, 0.2887487700, 0.2901394241, 0.2915320515, + 0.2929266392, 0.2943231740, 0.2957216428, 0.2971220325, 0.2985243300, 0.2999285219, + 0.3013345951, 0.3027425364, 0.3041523326, 0.3055639704, 0.3069774365, 0.3083927176, + 0.3098098005, 0.3112286717, 0.3126493180, 0.3140717260, 0.3154958823, 0.3169217735, + 0.3183493863, 0.3197787071, 0.3212097227, 0.3226424194, 0.3240767838, 0.3255128025, + 0.3269504619, 0.3283897485, 0.3298306489, 0.3312731493, 0.3327172363, 0.3341628964, + 0.3356101158, 0.3370588810, 0.3385091784, 0.3399609943, 0.3414143150, 0.3428691270, + 0.3443254166, 0.3457831699, 0.3472423734, 0.3487030133, 0.3501650759, 0.3516285474, + 0.3530934141, 0.3545596622, 0.3560272778, 0.3574962473, 0.3589665568, 0.3604381924, + 0.3619111404, 0.3633853868, 0.3648609179, 0.3663377196, 0.3678157783, 0.3692950799, + 0.3707756105, 0.3722573563, 0.3737403032, 0.3752244374, 0.3767097449, 0.3781962117, + 0.3796838239, 0.3811725674, 0.3826624282, 0.3841533924, 0.3856454460, 0.3871385748, + 0.3886327649, 0.3901280022, 0.3916242727, 0.3931215622, 0.3946198567, 0.3961191422, + 0.3976194044, 0.3991206294, 0.4006228029, 0.4021259109, 0.4036299393, 0.4051348738, + 0.4066407004, 0.4081474048, 0.4096549729, 0.4111633906, 0.4126726436, 0.4141827178, + 0.4156935990, 0.4172052728, 0.4187177253, 0.4202309420, 0.4217449088, 0.4232596115, + 0.4247750358, 0.4262911674, 0.4278079921, 0.4293254957, 0.4308436638, 0.4323624822, + 0.4338819366, 0.4354020128, 0.4369226964, 0.4384439731, 0.4399658286, 0.4414882486, + 0.4430112189, 0.4445347250, 0.4460587526, 0.4475832875, 0.4491083153, 0.4506338216, + 0.4521597921, 0.4536862125, 0.4552130684, 0.4567403454, 0.4582680291, 0.4597961053, + 0.4613245596, 0.4628533775, 0.4643825447, 0.4659120468, 0.4674418695, 0.4689719983, + 0.4705024189, 0.4720331168, 0.4735640778, 0.4750952873, 0.4766267310, 0.4781583944, + 0.4796902633, 0.4812223231, 0.4827545595, 0.4842869581, 0.4858195044, 0.4873521841, + 0.4888849827, 0.4904178858, 0.4919508790, 0.4934839479, 0.4950170780, 0.4965502551, + 0.4980834645, 0.4996166920, 0.5011499231, 0.5026831434, 0.5042163384, 0.5057494938, + 0.5072825951, 0.5088156280, 0.5103485780, 0.5118814306, 0.5134141715, 0.5149467863, + 0.5164792606, 0.5180115799, 0.5195437298, 0.5210756959, 0.5226074639, 0.5241390193, + 0.5256703477, 0.5272014347, 0.5287322659, 0.5302628270, 0.5317931035, 0.5333230810, + 0.5348527452, 0.5363820817, 0.5379110760, 0.5394397139, 0.5409679809, 0.5424958627, + 0.5440233449, 0.5455504131, 0.5470770530, 0.5486032503, 0.5501289905, 0.5516542593, + 0.5531790424, 0.5547033255, 0.5562270942, 0.5577503341, 0.5592730311, 0.5607951706, + 0.5623167385, 0.5638377205, 0.5653581021, 0.5668778692, 0.5683970074, 0.5699155024, + 0.5714333401, 0.5729505060, 0.5744669860, 0.5759827657, 0.5774978309, 0.5790121675, + 0.5805257610, 0.5820385974, 0.5835506623, 0.5850619416, 0.5865724210, 0.5880820864, + 0.5895909235, 0.5910989182, 0.5926060563, 0.5941123235, 0.5956177058, 0.5971221890, + 0.5986257590, 0.6001284015, 0.6016301025, 0.6031308479, 0.6046306235, 0.6061294153, + 0.6076272091, 0.6091239908, 0.6106197465, 0.6121144619, 0.6136081231, 0.6151007161, + 0.6165922267, 0.6180826410, 0.6195719449, 0.6210601245, 0.6225471657, 0.6240330546, + 0.6255177772, 0.6270013195, 0.6284836676, 0.6299648076, 0.6314447254, 0.6329234073, + 0.6344008392, 0.6358770074, 0.6373518979, 0.6388254968, 0.6402977903, 0.6417687646, + 0.6432384058, 0.6447067001, 0.6461736337, 0.6476391928, 0.6491033636, 0.6505661323, + 0.6520274853, 0.6534874087, 0.6549458889, 0.6564029120, 0.6578584645, 0.6593125326, + 0.6607651027, 0.6622161610, 0.6636656940, 0.6651136880, 0.6665601294, 0.6680050047, + 0.6694483001, 0.6708900022, 0.6723300973, 0.6737685721, 0.6752054128, 0.6766406060, + 0.6780741383, 0.6795059961, 0.6809361660, 0.6823646344, 0.6837913881, 0.6852164136, + 0.6866396974, 0.6880612262, 0.6894809866, 0.6908989653, 0.6923151490, 0.6937295243, + 0.6951420779, 0.6965527965, 0.6979616669, 0.6993686758, 0.7007738101, 0.7021770564, + 0.7035784016, 0.7049778325, 0.7063753360, 0.7077708989, 0.7091645081, 0.7105561504, + 0.7119458129, 0.7133334824, 0.7147191459, 0.7161027903, 0.7174844027, 0.7188639700, + 0.7202414793, 0.7216169176, 0.7229902721, 0.7243615297, 0.7257306776, 0.7270977029, + 0.7284625927, 0.7298253343, 0.7311859148, 0.7325443214, 0.7339005413, 0.7352545618, + 0.7366063702, 0.7379559537, 0.7393032997, 0.7406483955, 0.7419912284, 0.7433317858, + 0.7446700551, 0.7460060237, 0.7473396791, 0.7486710087, 0.7500000000, 0.7513266405, + 0.7526509177, 0.7539728192, 0.7552923326, 0.7566094454, 0.7579241452, 0.7592364197, + 0.7605462566, 0.7618536435, 0.7631585681, 0.7644610182, 0.7657609816, 0.7670584459, + 0.7683533990, 0.7696458288, 0.7709357230, 0.7722230696, 0.7735078563, 0.7747900713, + 0.7760697023, 0.7773467374, 0.7786211646, 0.7798929718, 0.7811621471, 0.7824286786, + 0.7836925544, 0.7849537626, 0.7862122913, 0.7874681286, 0.7887212629, 0.7899716822, + 0.7912193749, 0.7924643292, 0.7937065334, 0.7949459759, 0.7961826448, 0.7974165288, + 0.7986476160, 0.7998758950, 0.8011013543, 0.8023239822, 0.8035437673, 0.8047606981, + 0.8059747632, 0.8071859511, 0.8083942505, 0.8095996501, 0.8108021384, 0.8120017041, + 0.8131983361, 0.8143920230, 0.8155827536, 0.8167705167, 0.8179553012, 0.8191370958, + 0.8203158896, 0.8214916713, 0.8226644301, 0.8238341547, 0.8250008343, 0.8261644578, + 0.8273250143, 0.8284824929, 0.8296368828, 0.8307881730, 0.8319363527, 0.8330814112, + 0.8342233376, 0.8353621213, 0.8364977515, 0.8376302175, 0.8387595088, 0.8398856146, + 0.8410085244, 0.8421282276, 0.8432447138, 0.8443579723, 0.8454679928, 0.8465747647, + 0.8476782778, 0.8487785216, 0.8498754857, 0.8509691599, 0.8520595339, 0.8531465974, + 0.8542303401, 0.8553107520, 0.8563878228, 0.8574615425, 0.8585319008, 0.8595988878, + 0.8606624934, 0.8617227077, 0.8627795206, 0.8638329222, 0.8648829026, 0.8659294520, + 0.8669725604, 0.8680122182, 0.8690484154, 0.8700811424, 0.8711103895, 0.8721361469, + 0.8731584051, 0.8741771544, 0.8751923852, 0.8762040880, 0.8772122533, 0.8782168716, + 0.8792179335, 0.8802154295, 0.8812093502, 0.8821996864, 0.8831864286, 0.8841695677, + 0.8851490944, 0.8861249994, 0.8870972736, 0.8880659079, 0.8890308931, 0.8899922202, + 0.8909498801, 0.8919038639, 0.8928541624, 0.8938007669, 0.8947436684, 0.8956828581, + 0.8966183271, 0.8975500666, 0.8984780678, 0.8994023221, 0.9003228207, 0.9012395551, + 0.9021525164, 0.9030616963, 0.9039670861, 0.9048686773, 0.9057664615, 0.9066604301, + 0.9075505748, 0.9084368873, 0.9093193592, 0.9101979821, 0.9110727479, 0.9119436483, + 0.9128106750, 0.9136738201, 0.9145330753, 0.9153884325, 0.9162398838, 0.9170874211, + 0.9179310364, 0.9187707219, 0.9196064696, 0.9204382716, 0.9212661201, 0.9220900075, + 0.9229099258, 0.9237258674, 0.9245378246, 0.9253457899, 0.9261497555, 0.9269497139, + 0.9277456577, 0.9285375792, 0.9293254712, 0.9301093261, 0.9308891366, 0.9316648954, + 0.9324365952, 0.9332042287, 0.9339677886, 0.9347272679, 0.9354826594, 0.9362339559, + 0.9369811504, 0.9377242359, 0.9384632054, 0.9391980520, 0.9399287687, 0.9406553486, + 0.9413777850, 0.9420960710, 0.9428101999, 0.9435201650, 0.9442259596, 0.9449275770, + 0.9456250107, 0.9463182541, 0.9470073006, 0.9476921439, 0.9483727774, 0.9490491948, + 0.9497213897, 0.9503893558, 0.9510530868, 0.9517125764, 0.9523678185, 0.9530188069, + 0.9536655355, 0.9543079981, 0.9549461889, 0.9555801016, 0.9562097305, 0.9568350695, + 0.9574561128, 0.9580728546, 0.9586852890, 0.9592934103, 0.9598972128, 0.9604966908, + 0.9610918387, 0.9616826508, 0.9622691216, 0.9628512456, 0.9634290173, 0.9640024313, + 0.9645714822, 0.9651361647, 0.9656964734, 0.9662524030, 0.9668039484, 0.9673511043, + 0.9678938657, 0.9684322273, 0.9689661842, 0.9694957313, 0.9700208637, 0.9705415763, + 0.9710578644, 0.9715697230, 0.9720771473, 0.9725801326, 0.9730786742, 0.9735727673, + 0.9740624073, 0.9745475895, 0.9750283096, 0.9755045628, 0.9759763448, 0.9764436511, + 0.9769064773, 0.9773648190, 0.9778186720, 0.9782680320, 0.9787128947, 0.9791532560, + 0.9795891117, 0.9800204578, 0.9804472901, 0.9808696047, 0.9812873975, 0.9817006648, + 0.9821094025, 0.9825136068, 0.9829132740, 0.9833084002, 0.9836989818, 0.9840850151, + 0.9844664964, 0.9848434222, 0.9852157889, 0.9855835931, 0.9859468312, 0.9863054998, + 0.9866595956, 0.9870091153, 0.9873540555, 0.9876944131, 0.9880301847, 0.9883613673, + 0.9886879578, 0.9890099530, 0.9893273500, 0.9896401457, 0.9899483373, 0.9902519217, + 0.9905508963, 0.9908452580, 0.9911350043, 0.9914201323, 0.9917006395, 0.9919765230, + 0.9922477804, 0.9925144091, 0.9927764066, 0.9930337704, 0.9932864982, 0.9935345874, + 0.9937780359, 0.9940168412, 0.9942510013, 0.9944805137, 0.9947053765, 0.9949255875, + 0.9951411446, 0.9953520458, 0.9955582891, 0.9957598726, 0.9959567943, 0.9961490524, + 0.9963366452, 0.9965195708, 0.9966978276, 0.9968714138, 0.9970403278, 0.9972045681, + 0.9973641330, 0.9975190211, 0.9976692310, 0.9978147612, 0.9979556103, 0.9980917771, + 0.9982232602, 0.9983500584, 0.9984721705, 0.9985895954, 0.9987023320, 0.9988103791, + 0.9989137359, 0.9990124013, 0.9991063743, 0.9991956542, 0.9992802400, 0.9993601310, + 0.9994353264, 0.9995058256, 0.9995716277, 0.9996327323, 0.9996891388, 0.9997408466, + 0.9997878552, 0.9998301643, 0.9998677733, 0.9999006820, 0.9999288900, 0.9999523970, + 0.9999712030, 0.9999853076, 0.9999947107, 0.9999994123, 0.9999994123, 0.9999947107, + 0.9999853076, 0.9999712030, 0.9999523970, 0.9999288900, 0.9999006820, 0.9998677733, + 0.9998301643, 0.9997878552, 0.9997408466, 0.9996891388, 0.9996327323, 0.9995716277, + 0.9995058256, 0.9994353264, 0.9993601310, 0.9992802400, 0.9991956542, 0.9991063743, + 0.9990124013, 0.9989137359, 0.9988103791, 0.9987023320, 0.9985895954, 0.9984721705, + 0.9983500584, 0.9982232602, 0.9980917771, 0.9979556103, 0.9978147612, 0.9976692310, + 0.9975190211, 0.9973641330, 0.9972045681, 0.9970403278, 0.9968714138, 0.9966978276, + 0.9965195708, 0.9963366452, 0.9961490524, 0.9959567943, 0.9957598726, 0.9955582891, + 0.9953520458, 0.9951411446, 0.9949255875, 0.9947053765, 0.9944805137, 0.9942510013, + 0.9940168412, 0.9937780359, 0.9935345874, 0.9932864982, 0.9930337704, 0.9927764066, + 0.9925144091, 0.9922477804, 0.9919765230, 0.9917006395, 0.9914201323, 0.9911350043, + 0.9908452580, 0.9905508963, 0.9902519217, 0.9899483373, 0.9896401457, 0.9893273500, + 0.9890099530, 0.9886879578, 0.9883613673, 0.9880301847, 0.9876944131, 0.9873540555, + 0.9870091153, 0.9866595956, 0.9863054998, 0.9859468312, 0.9855835931, 0.9852157889, + 0.9848434222, 0.9844664964, 0.9840850151, 0.9836989818, 0.9833084002, 0.9829132740, + 0.9825136068, 0.9821094025, 0.9817006648, 0.9812873975, 0.9808696047, 0.9804472901, + 0.9800204578, 0.9795891117, 0.9791532560, 0.9787128947, 0.9782680320, 0.9778186720, + 0.9773648190, 0.9769064773, 0.9764436511, 0.9759763448, 0.9755045628, 0.9750283096, + 0.9745475895, 0.9740624073, 0.9735727673, 0.9730786742, 0.9725801326, 0.9720771473, + 0.9715697230, 0.9710578644, 0.9705415763, 0.9700208637, 0.9694957313, 0.9689661842, + 0.9684322273, 0.9678938657, 0.9673511043, 0.9668039484, 0.9662524030, 0.9656964734, + 0.9651361647, 0.9645714822, 0.9640024313, 0.9634290173, 0.9628512456, 0.9622691216, + 0.9616826508, 0.9610918387, 0.9604966908, 0.9598972128, 0.9592934103, 0.9586852890, + 0.9580728546, 0.9574561128, 0.9568350695, 0.9562097305, 0.9555801016, 0.9549461889, + 0.9543079981, 0.9536655355, 0.9530188069, 0.9523678185, 0.9517125764, 0.9510530868, + 0.9503893558, 0.9497213897, 0.9490491948, 0.9483727774, 0.9476921439, 0.9470073006, + 0.9463182541, 0.9456250107, 0.9449275770, 0.9442259596, 0.9435201650, 0.9428101999, + 0.9420960710, 0.9413777850, 0.9406553486, 0.9399287687, 0.9391980520, 0.9384632054, + 0.9377242359, 0.9369811504, 0.9362339559, 0.9354826594, 0.9347272679, 0.9339677886, + 0.9332042287, 0.9324365952, 0.9316648954, 0.9308891366, 0.9301093261, 0.9293254712, + 0.9285375792, 0.9277456577, 0.9269497139, 0.9261497555, 0.9253457899, 0.9245378246, + 0.9237258674, 0.9229099258, 0.9220900075, 0.9212661201, 0.9204382716, 0.9196064696, + 0.9187707219, 0.9179310364, 0.9170874211, 0.9162398838, 0.9153884325, 0.9145330753, + 0.9136738201, 0.9128106750, 0.9119436483, 0.9110727479, 0.9101979821, 0.9093193592, + 0.9084368873, 0.9075505748, 0.9066604301, 0.9057664615, 0.9048686773, 0.9039670861, + 0.9030616963, 0.9021525164, 0.9012395551, 0.9003228207, 0.8994023221, 0.8984780678, + 0.8975500666, 0.8966183271, 0.8956828581, 0.8947436684, 0.8938007669, 0.8928541624, + 0.8919038639, 0.8909498801, 0.8899922202, 0.8890308931, 0.8880659079, 0.8870972736, + 0.8861249994, 0.8851490944, 0.8841695677, 0.8831864286, 0.8821996864, 0.8812093502, + 0.8802154295, 0.8792179335, 0.8782168716, 0.8772122533, 0.8762040880, 0.8751923852, + 0.8741771544, 0.8731584051, 0.8721361469, 0.8711103895, 0.8700811424, 0.8690484154, + 0.8680122182, 0.8669725604, 0.8659294520, 0.8648829026, 0.8638329222, 0.8627795206, + 0.8617227077, 0.8606624934, 0.8595988878, 0.8585319008, 0.8574615425, 0.8563878228, + 0.8553107520, 0.8542303401, 0.8531465974, 0.8520595339, 0.8509691599, 0.8498754857, + 0.8487785216, 0.8476782778, 0.8465747647, 0.8454679928, 0.8443579723, 0.8432447138, + 0.8421282276, 0.8410085244, 0.8398856146, 0.8387595088, 0.8376302175, 0.8364977515, + 0.8353621213, 0.8342233376, 0.8330814112, 0.8319363527, 0.8307881730, 0.8296368828, + 0.8284824929, 0.8273250143, 0.8261644578, 0.8250008343, 0.8238341547, 0.8226644301, + 0.8214916713, 0.8203158896, 0.8191370958, 0.8179553012, 0.8167705167, 0.8155827536, + 0.8143920230, 0.8131983361, 0.8120017041, 0.8108021384, 0.8095996501, 0.8083942505, + 0.8071859511, 0.8059747632, 0.8047606981, 0.8035437673, 0.8023239822, 0.8011013543, + 0.7998758950, 0.7986476160, 0.7974165288, 0.7961826448, 0.7949459759, 0.7937065334, + 0.7924643292, 0.7912193749, 0.7899716822, 0.7887212629, 0.7874681286, 0.7862122913, + 0.7849537626, 0.7836925544, 0.7824286786, 0.7811621471, 0.7798929718, 0.7786211646, + 0.7773467374, 0.7760697023, 0.7747900713, 0.7735078563, 0.7722230696, 0.7709357230, + 0.7696458288, 0.7683533990, 0.7670584459, 0.7657609816, 0.7644610182, 0.7631585681, + 0.7618536435, 0.7605462566, 0.7592364197, 0.7579241452, 0.7566094454, 0.7552923326, + 0.7539728192, 0.7526509177, 0.7513266405, 0.7500000000, 0.7486710087, 0.7473396791, + 0.7460060237, 0.7446700551, 0.7433317858, 0.7419912284, 0.7406483955, 0.7393032997, + 0.7379559537, 0.7366063702, 0.7352545618, 0.7339005413, 0.7325443214, 0.7311859148, + 0.7298253343, 0.7284625927, 0.7270977029, 0.7257306776, 0.7243615297, 0.7229902721, + 0.7216169176, 0.7202414793, 0.7188639700, 0.7174844027, 0.7161027903, 0.7147191459, + 0.7133334824, 0.7119458129, 0.7105561504, 0.7091645081, 0.7077708989, 0.7063753360, + 0.7049778325, 0.7035784016, 0.7021770564, 0.7007738101, 0.6993686758, 0.6979616669, + 0.6965527965, 0.6951420779, 0.6937295243, 0.6923151490, 0.6908989653, 0.6894809866, + 0.6880612262, 0.6866396974, 0.6852164136, 0.6837913881, 0.6823646344, 0.6809361660, + 0.6795059961, 0.6780741383, 0.6766406060, 0.6752054128, 0.6737685721, 0.6723300973, + 0.6708900022, 0.6694483001, 0.6680050047, 0.6665601294, 0.6651136880, 0.6636656940, + 0.6622161610, 0.6607651027, 0.6593125326, 0.6578584645, 0.6564029120, 0.6549458889, + 0.6534874087, 0.6520274853, 0.6505661323, 0.6491033636, 0.6476391928, 0.6461736337, + 0.6447067001, 0.6432384058, 0.6417687646, 0.6402977903, 0.6388254968, 0.6373518979, + 0.6358770074, 0.6344008392, 0.6329234073, 0.6314447254, 0.6299648076, 0.6284836676, + 0.6270013195, 0.6255177772, 0.6240330546, 0.6225471657, 0.6210601245, 0.6195719449, + 0.6180826410, 0.6165922267, 0.6151007161, 0.6136081231, 0.6121144619, 0.6106197465, + 0.6091239908, 0.6076272091, 0.6061294153, 0.6046306235, 0.6031308479, 0.6016301025, + 0.6001284015, 0.5986257590, 0.5971221890, 0.5956177058, 0.5941123235, 0.5926060563, + 0.5910989182, 0.5895909235, 0.5880820864, 0.5865724210, 0.5850619416, 0.5835506623, + 0.5820385974, 0.5805257610, 0.5790121675, 0.5774978309, 0.5759827657, 0.5744669860, + 0.5729505060, 0.5714333401, 0.5699155024, 0.5683970074, 0.5668778692, 0.5653581021, + 0.5638377205, 0.5623167385, 0.5607951706, 0.5592730311, 0.5577503341, 0.5562270942, + 0.5547033255, 0.5531790424, 0.5516542593, 0.5501289905, 0.5486032503, 0.5470770530, + 0.5455504131, 0.5440233449, 0.5424958627, 0.5409679809, 0.5394397139, 0.5379110760, + 0.5363820817, 0.5348527452, 0.5333230810, 0.5317931035, 0.5302628270, 0.5287322659, + 0.5272014347, 0.5256703477, 0.5241390193, 0.5226074639, 0.5210756959, 0.5195437298, + 0.5180115799, 0.5164792606, 0.5149467863, 0.5134141715, 0.5118814306, 0.5103485780, + 0.5088156280, 0.5072825951, 0.5057494938, 0.5042163384, 0.5026831434, 0.5011499231, + 0.4996166920, 0.4980834645, 0.4965502551, 0.4950170780, 0.4934839479, 0.4919508790, + 0.4904178858, 0.4888849827, 0.4873521841, 0.4858195044, 0.4842869581, 0.4827545595, + 0.4812223231, 0.4796902633, 0.4781583944, 0.4766267310, 0.4750952873, 0.4735640778, + 0.4720331168, 0.4705024189, 0.4689719983, 0.4674418695, 0.4659120468, 0.4643825447, + 0.4628533775, 0.4613245596, 0.4597961053, 0.4582680291, 0.4567403454, 0.4552130684, + 0.4536862125, 0.4521597921, 0.4506338216, 0.4491083153, 0.4475832875, 0.4460587526, + 0.4445347250, 0.4430112189, 0.4414882486, 0.4399658286, 0.4384439731, 0.4369226964, + 0.4354020128, 0.4338819366, 0.4323624822, 0.4308436638, 0.4293254957, 0.4278079921, + 0.4262911674, 0.4247750358, 0.4232596115, 0.4217449088, 0.4202309420, 0.4187177253, + 0.4172052728, 0.4156935990, 0.4141827178, 0.4126726436, 0.4111633906, 0.4096549729, + 0.4081474048, 0.4066407004, 0.4051348738, 0.4036299393, 0.4021259109, 0.4006228029, + 0.3991206294, 0.3976194044, 0.3961191422, 0.3946198567, 0.3931215622, 0.3916242727, + 0.3901280022, 0.3886327649, 0.3871385748, 0.3856454460, 0.3841533924, 0.3826624282, + 0.3811725674, 0.3796838239, 0.3781962117, 0.3767097449, 0.3752244374, 0.3737403032, + 0.3722573563, 0.3707756105, 0.3692950799, 0.3678157783, 0.3663377196, 0.3648609179, + 0.3633853868, 0.3619111404, 0.3604381924, 0.3589665568, 0.3574962473, 0.3560272778, + 0.3545596622, 0.3530934141, 0.3516285474, 0.3501650759, 0.3487030133, 0.3472423734, + 0.3457831699, 0.3443254166, 0.3428691270, 0.3414143150, 0.3399609943, 0.3385091784, + 0.3370588810, 0.3356101158, 0.3341628964, 0.3327172363, 0.3312731493, 0.3298306489, + 0.3283897485, 0.3269504619, 0.3255128025, 0.3240767838, 0.3226424194, 0.3212097227, + 0.3197787071, 0.3183493863, 0.3169217735, 0.3154958823, 0.3140717260, 0.3126493180, + 0.3112286717, 0.3098098005, 0.3083927176, 0.3069774365, 0.3055639704, 0.3041523326, + 0.3027425364, 0.3013345951, 0.2999285219, 0.2985243300, 0.2971220325, 0.2957216428, + 0.2943231740, 0.2929266392, 0.2915320515, 0.2901394241, 0.2887487700, 0.2873601024, + 0.2859734343, 0.2845887787, 0.2832061487, 0.2818255572, 0.2804470173, 0.2790705418, + 0.2776961439, 0.2763238362, 0.2749536319, 0.2735855437, 0.2722195845, 0.2708557672, + 0.2694941045, 0.2681346094, 0.2667772945, 0.2654221727, 0.2640692567, 0.2627185591, + 0.2613700928, 0.2600238703, 0.2586799044, 0.2573382077, 0.2559987928, 0.2546616722, + 0.2533268587, 0.2519943646, 0.2506642026, 0.2493363851, 0.2480109247, 0.2466878338, + 0.2453671248, 0.2440488102, 0.2427329023, 0.2414194136, 0.2401083564, 0.2387997429, + 0.2374935856, 0.2361898967, 0.2348886885, 0.2335899731, 0.2322937629, 0.2310000699, + 0.2297089064, 0.2284202845, 0.2271342163, 0.2258507140, 0.2245697895, 0.2232914549, + 0.2220157223, 0.2207426036, 0.2194721108, 0.2182042559, 0.2169390508, 0.2156765073, + 0.2144166374, 0.2131594529, 0.2119049656, 0.2106531873, 0.2094041298, 0.2081578049, + 0.2069142242, 0.2056733994, 0.2044353422, 0.2032000643, 0.2019675773, 0.2007378927, + 0.1995110222, 0.1982869772, 0.1970657692, 0.1958474098, 0.1946319104, 0.1934192825, + 0.1922095374, 0.1910026865, 0.1897987412, 0.1885977127, 0.1873996124, 0.1862044516, + 0.1850122415, 0.1838229932, 0.1826367180, 0.1814534271, 0.1802731315, 0.1790958423, + 0.1779215707, 0.1767503277, 0.1755821242, 0.1744169713, 0.1732548799, 0.1720958610, + 0.1709399254, 0.1697870840, 0.1686373477, 0.1674907272, 0.1663472334, 0.1652068770, + 0.1640696688, 0.1629356193, 0.1618047394, 0.1606770395, 0.1595525304, 0.1584312225, + 0.1573131265, 0.1561982529, 0.1550866121, 0.1539782145, 0.1528730707, 0.1517711910, + 0.1506725857, 0.1495772653, 0.1484852399, 0.1473965199, 0.1463111155, 0.1452290369, + 0.1441502943, 0.1430748978, 0.1420028576, 0.1409341836, 0.1398688861, 0.1388069749, + 0.1377484601, 0.1366933516, 0.1356416593, 0.1345933932, 0.1335485631, 0.1325071788, + 0.1314692500, 0.1304347867, 0.1294037985, 0.1283762950, 0.1273522860, 0.1263317811, + 0.1253147898, 0.1243013218, 0.1232913866, 0.1222849936, 0.1212821523, 0.1202828722, + 0.1192871627, 0.1182950331, 0.1173064927, 0.1163215508, 0.1153402168, 0.1143624998, + 0.1133884090, 0.1124179537, 0.1114511428, 0.1104879855, 0.1095284909, 0.1085726679, + 0.1076205257, 0.1066720730, 0.1057273189, 0.1047862722, 0.1038489418, 0.1029153364, + 0.1019854650, 0.1010593361, 0.1001369586, 0.0992183410, 0.0983034921, 0.0973924204, + 0.0964851345, 0.0955816430, 0.0946819542, 0.0937860768, 0.0928940190, 0.0920057894, + 0.0911213962, 0.0902408477, 0.0893641523, 0.0884913182, 0.0876223536, 0.0867572667, + 0.0858960656, 0.0850387583, 0.0841853531, 0.0833358578, 0.0824902805, 0.0816486291, + 0.0808109116, 0.0799771357, 0.0791473095, 0.0783214406, 0.0774995368, 0.0766816058, + 0.0758676555, 0.0750576933, 0.0742517269, 0.0734497639, 0.0726518119, 0.0718578783, + 0.0710679706, 0.0702820963, 0.0695002626, 0.0687224770, 0.0679487469, 0.0671790793, + 0.0664134817, 0.0656519612, 0.0648945250, 0.0641411801, 0.0633919337, 0.0626467928, + 0.0619057644, 0.0611688555, 0.0604360730, 0.0597074238, 0.0589829148, 0.0582625528, + 0.0575463445, 0.0568342966, 0.0561264160, 0.0554227092, 0.0547231828, 0.0540278434, + 0.0533366976, 0.0526497519, 0.0519670127, 0.0512884865, 0.0506141795, 0.0499440982, + 0.0492782489, 0.0486166378, 0.0479592712, 0.0473061552, 0.0466572959, 0.0460126996, + 0.0453723721, 0.0447363196, 0.0441045481, 0.0434770634, 0.0428538715, 0.0422349782, + 0.0416203894, 0.0410101108, 0.0404041482, 0.0398025073, 0.0392051936, 0.0386122130, + 0.0380235708, 0.0374392727, 0.0368593242, 0.0362837306, 0.0357124975, 0.0351456301, + 0.0345831339, 0.0340250141, 0.0334712759, 0.0329219246, 0.0323769653, 0.0318364032, + 0.0313002433, 0.0307684907, 0.0302411503, 0.0297182272, 0.0291997263, 0.0286856523, + 0.0281760103, 0.0276708049, 0.0271700408, 0.0266737229, 0.0261818558, 0.0256944441, + 0.0252114924, 0.0247330052, 0.0242589870, 0.0237894423, 0.0233243755, 0.0228637910, + 0.0224076931, 0.0219560861, 0.0215089742, 0.0210663617, 0.0206282527, 0.0201946513, + 0.0197655616, 0.0193409877, 0.0189209335, 0.0185054029, 0.0180944000, 0.0176879285, + 0.0172859922, 0.0168885951, 0.0164957407, 0.0161074328, 0.0157236751, 0.0153444710, + 0.0149698243, 0.0145997385, 0.0142342169, 0.0138732631, 0.0135168805, 0.0131650723, + 0.0128178420, 0.0124751927, 0.0121371277, 0.0118036501, 0.0114747632, 0.0111504700, + 0.0108307735, 0.0105156768, 0.0102051828, 0.0098992944, 0.0095980146, 0.0093013461, + 0.0090092917, 0.0087218542, 0.0084390363, 0.0081608407, 0.0078872699, 0.0076183265, + 0.0073540131, 0.0070943321, 0.0068392860, 0.0065888773, 0.0063431081, 0.0061019809, + 0.0058654980, 0.0056336614, 0.0054064735, 0.0051839364, 0.0049660521, 0.0047528227, + 0.0045442502, 0.0043403366, 0.0041410837, 0.0039464936, 0.0037565679, 0.0035713085, + 0.0033907171, 0.0032147954, 0.0030435451, 0.0028769677, 0.0027150650, 0.0025578382, + 0.0024052891, 0.0022574189, 0.0021142290, 0.0019757209, 0.0018418958, 0.0017127550, + 0.0015882997, 0.0014685311, 0.0013534502, 0.0012430582, 0.0011373561, 0.0010363449, + 0.0009400256, 0.0008483991, 0.0007614661, 0.0006792276, 0.0006016843, 0.0005288369, + 0.0004606862, 0.0003972327, 0.0003384771, 0.0002844199, 0.0002350617, 0.0001904028, + 0.0001504437, 0.0001151848, 0.0000846264, 0.0000587689, 0.0000376123, 0.0000211571, + 0.0000094032, 0.0000023508}; -#endif // HANNING_H \ No newline at end of file +#endif // LIB_UTILS_HANNING_H_ diff --git a/lib/utils/ring_buffer.h b/lib/utils/ring_buffer.h index a207127..6599083 100644 --- a/lib/utils/ring_buffer.h +++ b/lib/utils/ring_buffer.h @@ -1,32 +1,45 @@ -#ifndef RING_BUFFER_H -#define RING_BUFFER_H +#ifndef LIB_UTILS_RING_BUFFER_H_ +#define LIB_UTILS_RING_BUFFER_H_ #include -template -class RingBuffer : private std::vector +template class RingBuffer : private std::vector { -public: - RingBuffer(std::size_t size, T&& defaultValue = T()); + public: + explicit RingBuffer(std::size_t size, T &&default_value = T()); virtual ~RingBuffer(); - void Append(const T& value); - std::uint32_t Size() const { return std::vector::size(); } - std::uint32_t& NumWritten() { return mNumWritten; } - std::uint32_t& Position() { return mPosition; } + void Append(const T &value); + std::uint32_t size() const + { + return std::vector::size(); + } + std::uint32_t &num_written() + { + return num_written_; + } + std::uint32_t &position() + { + return position_; + } + + T &operator[](std::int32_t index); - T& operator[](std::int32_t index); - - typename std::vector::iterator begin() { return std::vector::begin(); } - typename std::vector::iterator end() { return std::vector::end(); } + typename std::vector::iterator begin() + { + return std::vector::begin(); + } + typename std::vector::iterator end() + { + return std::vector::end(); + } -private: - std::uint32_t mNumWritten; - std::uint32_t mPosition; + private: + std::uint32_t num_written_; + std::uint32_t position_; }; -template -T& RingBuffer::operator[](std::int32_t index) +template T &RingBuffer::operator[](std::int32_t index) { if (index < 0) { @@ -37,24 +50,20 @@ T& RingBuffer::operator[](std::int32_t index) } template -RingBuffer::RingBuffer(std::size_t size, T&& defaultValue) - : std::vector(size, defaultValue) - , mNumWritten(0) - , mPosition(0) +RingBuffer::RingBuffer(std::size_t size, T &&default_value) + : std::vector(size, default_value), num_written_(0), position_(0) { } -template -RingBuffer::~RingBuffer() +template RingBuffer::~RingBuffer() { } -template -void RingBuffer::Append(const T& value) +template void RingBuffer::Append(const T &value) { - this->operator[](mPosition) = value; - mPosition = (mPosition + 1) % std::vector::size(); - mNumWritten++; + this->operator[](position_) = value; + position_ = (position_ + 1) % std::vector::size(); + num_written_++; } -#endif // RING_BUFFER_H \ No newline at end of file +#endif // LIB_UTILS_RING_BUFFER_H_ diff --git a/lib/utils/uuid4.h b/lib/utils/uuid4.h index f09af8b..df563b0 100644 --- a/lib/utils/uuid4.h +++ b/lib/utils/uuid4.h @@ -1,5 +1,5 @@ -#ifndef __UUID4_H__ -#define __UUID4_H__ +#ifndef LIB_UTILS_UUID4_H_ +#define LIB_UTILS_UUID4_H_ #include #include @@ -8,43 +8,43 @@ namespace uuid4 { - std::string generate() - { - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(0, 15); - std::uniform_int_distribution<> dis2(8, 11); - - std::stringstream ss; - ss << std::hex; - for (int i = 0; i < 8; i++) - { - ss << dis(gen); - } - ss << "-"; - for (int i = 0; i < 4; i++) - { - ss << dis(gen); - } - ss << "-4"; - for (int i = 0; i < 3; i++) - { - ss << dis(gen); - } - ss << "-"; - ss << dis2(gen); - for (int i = 0; i < 3; i++) - { - ss << dis(gen); - } - ss << "-"; - for (int i = 0; i < 12; i++) - { - ss << dis(gen); - } +std::string generate() +{ + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, 15); + std::uniform_int_distribution<> dis2(8, 11); - return ss.str(); // RVO. Guaranteed copy elision since C++17 + std::stringstream ss; + ss << std::hex; + for (int i = 0; i < 8; i++) + { + ss << dis(gen); } + ss << "-"; + for (int i = 0; i < 4; i++) + { + ss << dis(gen); + } + ss << "-4"; + for (int i = 0; i < 3; i++) + { + ss << dis(gen); + } + ss << "-"; + ss << dis2(gen); + for (int i = 0; i < 3; i++) + { + ss << dis(gen); + } + ss << "-"; + for (int i = 0; i < 12; i++) + { + ss << dis(gen); + } + + return ss.str(); // RVO. Guaranteed copy elision since C++17 } +} // namespace uuid4 -#endif // __UUID4_H__ +#endif // LIB_UTILS_UUID4_H_ diff --git a/lib/vibra.cpp b/lib/vibra.cpp index 737e3ff..b7ca77c 100644 --- a/lib/vibra.cpp +++ b/lib/vibra.cpp @@ -1,15 +1,15 @@ #include "../include/vibra.h" -#include "communication/shazam.h" #include "algorithm/signature_generator.h" #include "audio/downsampler.h" #include "audio/wav.h" +#include "communication/shazam.h" #include "utils/ffmpeg.h" -Fingerprint* _get_fingerprint_from_wav(const Wav& wav); +Fingerprint *_get_fingerprint_from_wav(const Wav &wav); -Fingerprint* _get_fingerprint_from_low_quality_pcm(const LowQualityTrack& pcm); +Fingerprint *_get_fingerprint_from_low_quality_pcm(const LowQualityTrack &pcm); -Fingerprint* vibra_get_fingerprint_from_music_file(const char* music_file_path) +Fingerprint *vibra_get_fingerprint_from_music_file(const char *music_file_path) { std::string path = music_file_path; if (path.size() >= 4 && path.substr(path.size() - 4) == ".wav") @@ -19,75 +19,79 @@ Fingerprint* vibra_get_fingerprint_from_music_file(const char* music_file_path) } LowQualityTrack pcm; - ffmpeg::FFmpegWrapper::convertToWav(path, &pcm); + ffmpeg::FFmpegWrapper::ConvertToWav(path, &pcm); return _get_fingerprint_from_low_quality_pcm(pcm); } -Fingerprint* vibra_get_fingerprint_from_wav_data(const char* raw_wav, int wav_data_size) +Fingerprint *vibra_get_fingerprint_from_wav_data(const char *raw_wav, int wav_data_size) { Wav wav = Wav::FromRawWav(raw_wav, wav_data_size); return _get_fingerprint_from_wav(wav); } -Fingerprint* vibra_get_fingerprint_from_signed_pcm(const char* raw_pcm, int pcm_data_size, int sample_rate, int sample_width, int channel_count) +Fingerprint *vibra_get_fingerprint_from_signed_pcm(const char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count) { Wav wav = Wav::FromSignedPCM(raw_pcm, pcm_data_size, sample_rate, sample_width, channel_count); return _get_fingerprint_from_wav(wav); } -Fingerprint* vibra_get_fingerprint_from_float_pcm(const char* raw_pcm, int pcm_data_size, int sample_rate, int sample_width, int channel_count) +Fingerprint *vibra_get_fingerprint_from_float_pcm(const char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count) { Wav wav = Wav::FromFloatPCM(raw_pcm, pcm_data_size, sample_rate, sample_width, channel_count); return _get_fingerprint_from_wav(wav); } -const char* vibra_get_uri_from_fingerprint(Fingerprint* fingerprint) +const char *vibra_get_uri_from_fingerprint(Fingerprint *fingerprint) { return fingerprint->uri.c_str(); } -unsigned int vibra_get_sample_ms_from_fingerprint(Fingerprint* fingerprint) +unsigned int vibra_get_sample_ms_from_fingerprint(Fingerprint *fingerprint) { return fingerprint->sample_ms; } -const char* vibra_get_shazam_request_json(const Fingerprint* fingerprint) +const char *vibra_get_shazam_request_json(const Fingerprint *fingerprint) { static std::string content; content = Shazam::GetRequestContent(fingerprint->uri, fingerprint->sample_ms); return content.c_str(); } -const char* vibra_get_shazam_host() +const char *vibra_get_shazam_host() { static std::string host; host = Shazam::GetShazamHost(); return host.c_str(); } -const char* vibra_get_shazam_random_user_agent() +const char *vibra_get_shazam_random_user_agent() { static std::string user_agent; user_agent = Shazam::GetUserAgent(); return user_agent.c_str(); } -Fingerprint* _get_fingerprint_from_wav(const Wav& wav) +Fingerprint *_get_fingerprint_from_wav(const Wav &wav) { LowQualityTrack pcm = Downsampler::GetLowQualityPCM(wav); return _get_fingerprint_from_low_quality_pcm(pcm); } -Fingerprint* _get_fingerprint_from_low_quality_pcm(const LowQualityTrack& pcm) +Fingerprint *_get_fingerprint_from_low_quality_pcm(const LowQualityTrack &pcm) { SignatureGenerator generator; generator.FeedInput(pcm); - generator.SetMaxTimeSeconds(12); + generator.set_max_time_seconds(12); Signature signature = generator.GetNextSignature(); - + static Fingerprint fingerprint; - fingerprint.uri = signature.GetBase64Uri(); - fingerprint.sample_ms = signature.NumberOfSamples() * 1000 / signature.SampleRate(); + fingerprint.uri = signature.EncodeBase64(); + fingerprint.sample_ms = signature.num_samples() * 1000 / signature.sample_rate(); return &fingerprint; -} \ No newline at end of file +} diff --git a/tests/test.sh b/tests/test.sh index 324c127..67620b6 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -2,7 +2,10 @@ set -e +TEST_TARGET=sample.mp3 +TEST_TARGET_TITLE="Misty" VIBRA_CLI=vibra +SHAZAM_REQUEST_DELAY=${1:-3} FAILED=0 function pass() { @@ -18,16 +21,10 @@ function info() { printf " - %s\t" "$1" } -function download_audio() { - local url=$1 - local format=$2 - local output=$3 - yt-dlp -x --audio-format "$format" -o "$output" "$url" > /dev/null -} - function recognize_audio() { local file=$1 $VIBRA_CLI --recognize --file "$file" | jq .track.title -r + sleep "$SHAZAM_REQUEST_DELAY" } function check_title() { @@ -41,16 +38,16 @@ function check_title() { } function test_audio_file() { - local url=$1 - local format=$2 + local extension=$1 + local file=$2 local expected_title=$3 - local file="/tmp/test.$format" - info "Testing $format file..." - download_audio "$url" "$format" "$file" + local temp_file="/tmp/test.$extension" + ffmpeg -y -i "$file" -f "$extension" "$temp_file" > /dev/null 2>&1 + info "Testing $temp_file..." local title - title=$(recognize_audio "$file") + title=$(recognize_audio "$temp_file") check_title "$expected_title" "$title" } @@ -58,12 +55,8 @@ function test_raw_pcm() { info "Testing raw PCM data..." echo - local url=$1 - local format=$2 - local expected_title=$3 - local file="/tmp/test_stdin.$format" - - download_audio "$url" "$format" "$file" + local file=$1 + local expected_title=$2 for type in signed float; do for bit in 16 24 32 64; do @@ -80,7 +73,7 @@ function test_raw_pcm() { $VIBRA_CLI --recognize --seconds 5 --rate $rate --channels $channels --bits $bit --$type | \ jq .track.title -r) check_title "$expected_title" "$title" - sleep 3 + sleep "$SHAZAM_REQUEST_DELAY" done done done @@ -93,10 +86,10 @@ function run_tests() { echo "Running vibra tests..." echo - test_audio_file "https://www.youtube.com/watch?v=QkF3oxziUI4" "wav" "Stairway to Heaven" - test_audio_file "https://www.youtube.com/watch?v=n4RjJKxsamQ" "mp3" "Wind of Change" - test_audio_file "https://www.youtube.com/watch?v=qQzdAsjWGPg" "flac" "My Way" - test_raw_pcm "https://www.youtube.com/watch?v=mQER0A0ej0M" "wav" "Hey Jude" + test_audio_file "wav" "$TEST_TARGET" "$TEST_TARGET_TITLE" + test_audio_file "mp3" "$TEST_TARGET" "$TEST_TARGET_TITLE" + test_audio_file "flac" "$TEST_TARGET" "$TEST_TARGET_TITLE" + test_raw_pcm "$TEST_TARGET" "$TEST_TARGET_TITLE" echo if [ $FAILED -eq 1 ]; then diff --git a/wasm/wasm.cpp b/wasm/wasm.cpp index 5a6a6d4..bdf3f74 100644 --- a/wasm/wasm.cpp +++ b/wasm/wasm.cpp @@ -1,69 +1,42 @@ #include -#include #include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -Fingerprint* EMSCRIPTEN_KEEPALIVE GetWavSignature( - char* raw_wav, - int wav_data_size) +Fingerprint *EMSCRIPTEN_KEEPALIVE GetWavSignature(char *raw_wav, int wav_data_size) { - return vibra_get_fingerprint_from_wav_data( - raw_wav, - wav_data_size - ); + return vibra_get_fingerprint_from_wav_data(raw_wav, wav_data_size); } -Fingerprint* EMSCRIPTEN_KEEPALIVE GetSignedPcmSignature( - char* raw_pcm, - int pcm_data_size, - int sample_rate, - int sample_width, - int channel_count) +Fingerprint *EMSCRIPTEN_KEEPALIVE GetSignedPcmSignature(char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count) { - return vibra_get_fingerprint_from_signed_pcm( - raw_pcm, - pcm_data_size, - sample_rate, - sample_width, - channel_count - ); + return vibra_get_fingerprint_from_signed_pcm(raw_pcm, pcm_data_size, sample_rate, sample_width, + channel_count); } -Fingerprint* EMSCRIPTEN_KEEPALIVE GetFloatPcmSignature( - char* raw_pcm, - int pcm_data_size, - int sample_rate, - int sample_width, - int channel_count) +Fingerprint *EMSCRIPTEN_KEEPALIVE GetFloatPcmSignature(char *raw_pcm, int pcm_data_size, + int sample_rate, int sample_width, + int channel_count) { - return vibra_get_fingerprint_from_float_pcm( - raw_pcm, - pcm_data_size, - sample_rate, - sample_width, - channel_count - ); + return vibra_get_fingerprint_from_float_pcm(raw_pcm, pcm_data_size, sample_rate, sample_width, + channel_count); } -const char* EMSCRIPTEN_KEEPALIVE GetFingerprint( - Fingerprint* signature) +const char *EMSCRIPTEN_KEEPALIVE GetFingerprint(Fingerprint *signature) { - return vibra_get_uri_from_fingerprint( - signature - ); + return vibra_get_uri_from_fingerprint(signature); } -unsigned int EMSCRIPTEN_KEEPALIVE GetSampleMs( - Fingerprint* signature) +unsigned int EMSCRIPTEN_KEEPALIVE GetSampleMs(Fingerprint *signature) { - return vibra_get_sample_ms_from_fingerprint( - signature - ); + return vibra_get_sample_ms_from_fingerprint(signature); } #ifdef __cplusplus } -#endif \ No newline at end of file +#endif