Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Write sample values of an exponentially-decaying sine wave to file.
- Takes arguments in MIDI note number and dB amplitude.
- Can plot with gnuplot: plot "filename".
- */
- #include <iostream>
- #include <cmath>
- #include <cstdlib>
- #include <cstdio>
- #ifndef M_PI
- #define M_PI 3.141592654
- #endif
- enum class args
- {
- name, outfile, dur, midinote, amp, sr, num_args
- };
- double mtof(int m)
- {
- const double c0 = 8.2070625;
- double st_ratio = pow(2, 1/12.0);
- auto f = c0 * pow(st_ratio, static_cast<double>(m));
- return f;
- }
- int ftom(double f)
- {
- const double c0 = 8.2070625;
- double semitone_ratio = pow(2, 1/12.0);
- double approx_m = log(f / c0) / log(semitone_ratio);
- auto m = static_cast<int>(lround(approx_m ));
- return m;
- }
- double dbtoa(double db)
- {
- double a = pow(10, db / 20);
- return a;
- }
- double atodb(double a)
- {
- double db = 20 * log(a);
- return db;
- }
- FILE *open_file(const char *outfile)
- {
- FILE* file = fopen(outfile, "w");
- if (file == nullptr)
- {
- printf("Error creating output file: %s\n", outfile);
- }
- return file;
- }
- void sine2txt(const char *outfile, double dur, int midi_note, double amp, int sr)
- {
- double start = 1.0;
- double end = dbtoa(-80.0);
- double ymax = 0.0;
- int n = (int)(dur * sr);
- double ramp = pow(end / start, 1.0 / n);
- FILE *file = open_file(outfile);
- for (auto x = 0; x < n; ++x)
- {
- double y = dbtoa(amp) * sin(2 * M_PI * mtof(midi_note) / sr * x);
- y *= start;
- start *= ramp;
- fprintf(file, "%.81f\n", y);
- if (fabs(y) > ymax)
- {
- ymax = fabs(y);
- }
- }
- fclose(file);
- printf("Done.\nMax sample value: %.81f\n", ymax);
- }
- int show_usage(int argc)
- {
- if (argc != int(args::num_args))
- {
- printf("Usage: sine2text <outfile> <duration> <MIDI note> <amplitude (dB)> <sample rate>\n");
- return 1;
- }
- return 0;
- }
- int main(int argc, char *argv[])
- {
- if (show_usage(argc)) exit(1);
- const char *outfile = argv[int(args::outfile)];
- double dur = atof(argv[int(args::dur)]);
- int midi_note = atoi(argv[int(args::midinote)]);
- double amp = atof((argv[int(args::amp)]));
- int sr = atoi(argv[int(args::sr)]);
- printf("Duration: %f\n", dur);
- printf("MIDI Note: %d\n", midi_note);
- printf("Amplitude (dB): %f\n", amp);
- printf("Sample Rate: %d\n", sr);
- printf("\n");
- sine2txt(outfile, dur, midi_note, amp, sr);
- return 0;
- }
Add Comment
Please, Sign In to add comment