Guest User

Untitled

a guest
Nov 14th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.42 KB | None | 0 0
  1. /*
  2. Write sample values of an exponentially-decaying sine wave to file.
  3. Takes arguments in MIDI note number and dB amplitude.
  4. Can plot with gnuplot: plot "filename".
  5. */
  6.  
  7. #include <iostream>
  8. #include <cmath>
  9. #include <cstdlib>
  10. #include <cstdio>
  11.  
  12. #ifndef M_PI
  13. #define M_PI 3.141592654
  14. #endif
  15.  
  16. enum class args
  17. {
  18. name, outfile, dur, midinote, amp, sr, num_args
  19. };
  20.  
  21. double mtof(int m)
  22. {
  23. const double c0 = 8.2070625;
  24. double st_ratio = pow(2, 1/12.0);
  25. auto f = c0 * pow(st_ratio, static_cast<double>(m));
  26. return f;
  27. }
  28.  
  29. int ftom(double f)
  30. {
  31. const double c0 = 8.2070625;
  32. double semitone_ratio = pow(2, 1/12.0);
  33. double approx_m = log(f / c0) / log(semitone_ratio);
  34. auto m = static_cast<int>(lround(approx_m ));
  35. return m;
  36. }
  37.  
  38. double dbtoa(double db)
  39. {
  40. double a = pow(10, db / 20);
  41. return a;
  42. }
  43.  
  44. double atodb(double a)
  45. {
  46. double db = 20 * log(a);
  47. return db;
  48. }
  49.  
  50. FILE *open_file(const char *outfile)
  51. {
  52. FILE* file = fopen(outfile, "w");
  53.  
  54. if (file == nullptr)
  55. {
  56. printf("Error creating output file: %s\n", outfile);
  57. }
  58.  
  59. return file;
  60. }
  61.  
  62. void sine2txt(const char *outfile, double dur, int midi_note, double amp, int sr)
  63. {
  64. double start = 1.0;
  65. double end = dbtoa(-80.0);
  66. double ymax = 0.0;
  67. int n = (int)(dur * sr);
  68. double ramp = pow(end / start, 1.0 / n);
  69. FILE *file = open_file(outfile);
  70.  
  71. for (auto x = 0; x < n; ++x)
  72. {
  73. double y = dbtoa(amp) * sin(2 * M_PI * mtof(midi_note) / sr * x);
  74. y *= start;
  75. start *= ramp;
  76. fprintf(file, "%.81f\n", y);
  77. if (fabs(y) > ymax)
  78. {
  79. ymax = fabs(y);
  80. }
  81. }
  82.  
  83. fclose(file);
  84. printf("Done.\nMax sample value: %.81f\n", ymax);
  85. }
  86.  
  87. int show_usage(int argc)
  88. {
  89. if (argc != int(args::num_args))
  90. {
  91. printf("Usage: sine2text <outfile> <duration> <MIDI note> <amplitude (dB)> <sample rate>\n");
  92. return 1;
  93. }
  94.  
  95. return 0;
  96. }
  97.  
  98. int main(int argc, char *argv[])
  99. {
  100. if (show_usage(argc)) exit(1);
  101.  
  102. const char *outfile = argv[int(args::outfile)];
  103. double dur = atof(argv[int(args::dur)]);
  104. int midi_note = atoi(argv[int(args::midinote)]);
  105. double amp = atof((argv[int(args::amp)]));
  106. int sr = atoi(argv[int(args::sr)]);
  107.  
  108. printf("Duration: %f\n", dur);
  109. printf("MIDI Note: %d\n", midi_note);
  110. printf("Amplitude (dB): %f\n", amp);
  111. printf("Sample Rate: %d\n", sr);
  112. printf("\n");
  113.  
  114. sine2txt(outfile, dur, midi_note, amp, sr);
  115.  
  116. return 0;
  117. }
Add Comment
Please, Sign In to add comment