Last active
June 12, 2020 21:56
-
-
Save SignalWhisperer/94046ff35a7141eb6d55fd3492b1ce15 to your computer and use it in GitHub Desktop.
Audio LFO example using C++17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <cstdint> | |
#include <fstream> | |
#include <vector> | |
#include <filesystem> | |
void work(const std::int16_t* signal, std::int16_t* new_signal, std::size_t num_samples) | |
{ | |
// Parameters | |
const double LFO_FREQUENCY = 5; // LFO frequency [Hz] | |
const double SAMPLE_RATE = 44100; // Sample rate [Hz] | |
const double CONVERSION_FACTOR = 32768.0; | |
double phase = 0; // Initial phase [rad] | |
double dphase = 2 * M_PI * LFO_FREQUENCY / SAMPLE_RATE; // Phase rate of change [rad/sample] | |
const double LFO_WEIGHT = 0.3; // Maximum amplitude variation of the LFO | |
const double LFO_OFFSET = 0.5; // Offset of the LFO amplitude | |
std::size_t n; | |
for (n = 0; n < num_samples; ++n) { | |
// Convert the input signal to a double and multiply by the LFO output | |
double sample = (signal[n] / CONVERSION_FACTOR) * (std::sin(phase) * LFO_WEIGHT + LFO_OFFSET); | |
// Increment the phase of the LFO by 1 sample, keep it within 2pi | |
phase = std::fmod(phase + dphase, 2*M_PI); | |
// Convert the sample to be used in the audio output | |
new_signal[n] = sample * CONVERSION_FACTOR; | |
} | |
} | |
int main(int, char**) | |
{ | |
std::filesystem::path in_path("sine.raw"); | |
std::filesystem::path out_path("lfo.raw"); | |
std::size_t in_size = std::filesystem::file_size(in_path); | |
std::size_t num_samples = in_size / sizeof(std::int16_t); | |
std::vector<std::int16_t> in(in_size / sizeof(std::int16_t)); | |
std::vector<std::int16_t> out(in_size / sizeof(std::int16_t)); | |
std::ifstream fin(in_path, std::ifstream::binary); | |
fin.read(reinterpret_cast<char*>(in.data()), in_size); | |
fin.close(); | |
work(in.data(), out.data(), in.size()); | |
std::ofstream fout(out_path, std::ofstream::binary); | |
fout.write(reinterpret_cast<const char*>(out.data()), out.size() * sizeof(std::int16_t)); | |
fout.close(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment