~mrp/aerodramus

99ed7583ab98f525898b649bb20d29dc2f68ebe7 — Mark Penner 5 months ago c90878c
update generate_signal
3 files changed, 16 insertions(+), 15 deletions(-)

M autotests/lib/aerodramus.test.cpp
M src/lib/aerodramus.cpp
M src/lib/aerodramus.h
M autotests/lib/aerodramus.test.cpp => autotests/lib/aerodramus.test.cpp +6 -7
@@ 22,13 22,12 @@ private Q_SLOTS:

void TestLibAerodramus::test_generate_signal()
{
    std::vector<int> expected = {61184633,    129059814,   204269818,   287478906,   379351158,  480519331,  591538390,   712818012,   844526607,
                                 986457416,   1137845183,  1297120045,  1461584630,  1627002232, 1787091105, 1932936664,  2052366558,  2129392880,
                                 2143923851,  2072096976,  1887792290,  1566127054,  1089928209, 460115362,  -289817293,  -1077151066, -1757393247,
                                 -2128978411, -1975804824, -1168527983, 177852028,   1561041018, 2144286110, 1239224076,  -807298129,  -2141529257,
                                 -859537778,  1756478078,  1321907844,  -1835921813, -513399919, 2069999894, -1818534422, 904469646};
    QCOMPARE(Aerodramus::generate_signal(200, 20000, 0.001, 44100), expected);
    long sample_rate{44100};
    double length{20};
    std::vector<double> data{Aerodramus::generate_signal(200, 20000, length, sample_rate)};
    QCOMPARE(data.size(), length * sample_rate);
}

void TestLibAerodramus::test_SoundFile()
{
    Aerodramus::SoundFile soundfile1{};


@@ 47,7 46,7 @@ void TestLibAerodramus::test_SoundFile()
    QVERIFY2(Aerodramus::write(soundfile1), "writing a file with a valid path and valid format, channel, and samplerate should succeed");
    Aerodramus::SoundFile soundfile2{Aerodramus::read(path)};
    QCOMPARE(soundfile2.sample_data.size(), expected_size);
    data = {0.1, 0.2, 1, 400.2, 0, -1111.22};
    data = Aerodramus::generate_signal(200, 20000, 20, 44100);
    expected_size = data.size();
    soundfile1.sample_data = data;
    soundfile1.format = SF_FORMAT_WAV | SF_FORMAT_PCM_32;

M src/lib/aerodramus.cpp => src/lib/aerodramus.cpp +9 -7
@@ 12,6 12,7 @@
#include <vector>

#include <sndfile.hh>

Aerodramus::SoundFile::SoundFile(long int size)
    : sample_data(size)
{


@@ 39,21 40,22 @@ bool Aerodramus::write(SoundFile const &soundfile)
        return false;
    }
}
std::vector<int> Aerodramus::generate_signal(int start_freq, int end_freq, float seconds, int sample_rate)

std::vector<double> Aerodramus::generate_signal(double start_freq, double end_freq, double seconds, long sample_rate)
{
    std::vector<int> data{};
    std::vector<double> data{};
    const double TAU{std::numbers::pi * 2};
    const int samples{static_cast<int>(seconds * sample_rate)};
    const double base{std::pow((end_freq / static_cast<double>(start_freq)), (1.0 / samples))};
    const unsigned long samples{static_cast<unsigned long>(seconds * sample_rate)};
    const double base{std::pow((end_freq / start_freq), (1.0 / samples))};
    // we need to keep track of the phase since the frequency will not be constant
    double prev_phase{0};
    for (int t = 0; t < samples; t++) {
    for (unsigned long t = 0; t < samples; ++t) {
        double freq{start_freq * std::pow(base, t)};
        // since we know the phase of the previous sample, we can ignore the time
        double phase{TAU * freq * (1.0 / sample_rate) + prev_phase};
        double x{(INT_MAX * std::sin(phase))};
        double x{1.0 * std::sin(phase)};
        prev_phase = phase;
        if (data.size() > static_cast<uint>(t)) {
        if (data.size() > t) {
            data[t] = x;
        } else {
            data.push_back(x);

M src/lib/aerodramus.h => src/lib/aerodramus.h +1 -1
@@ 22,7 22,7 @@ struct SoundFile {
SoundFile read(std::string const &path);
bool write(SoundFile const &soundfile);

std::vector<int> generate_signal(int start_freq, int end_freq, float seconds, int sample_rate);
std::vector<double> generate_signal(double start_freq, double end_freq, double seconds, long sample_rate);
double dB_from_point_source(double sensitivity, double distance, double watts);
double watts_needed_to_point_source(double sensitivity, double distance, double dB);
std::vector<int> zero_cross_histogram(const std::vector<float> &samples, int bins);