Last active
June 12, 2020 21:29
-
-
Save SignalWhisperer/28528fc1b8993f0856bc7ef9d22e4bb2 to your computer and use it in GitHub Desktop.
Audio LFO example using C++11
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 <string> | |
#include <limits> | |
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::string in_path("sine.raw"); | |
std::string out_path("lfo.raw"); | |
std::ifstream fin(in_path, std::ifstream::binary); | |
// get the file size | |
fin.ignore(std::numeric_limits<std::streamsize>::max()); | |
std::streamsize in_size = fin.gcount(); | |
fin.clear(); | |
fin.seekg(0, std::ios_base::beg); | |
// prepare the data arrays | |
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)); | |
// read the contents | |
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