/[svn]/linuxsampler/trunk/benchmarks/sine.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/benchmarks/sine.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3612 - (hide annotations) (download)
Mon Sep 30 18:03:43 2019 UTC (4 years, 6 months ago) by schoenebeck
File size: 5166 byte(s)
Added new LFO implementations:

* Added int math square LFO implementation.

* Added int math saw LFO implementation.

* Added numeric complex nr sine LFO implementation.

* Added public API C++ class "LFO", which is a cluster class
  encapsulating all the sampler's LFO implementations to be used by
  3rd party applications (e.g. by Gigedit).

* Marked class LFOTriangleDiHarmonic as deprecated
  (will be removed in future).

* Added LFOAll.h which includes all LFO implementation's header files.

* Fixed benchmarks/triang.cpp falsely having favoured "int math abs"
  algorithm (since result of 2nd run was not accumulated).

* Added benchmark for saw wave (benchmarks/saw.cpp).

* Added benchmark for sine wave (benchmarks/sine.cpp).

* Added benchmark for square wave (benchmarks/square.cpp).

* Increased amount of benchmarks runs by factor 6 to achieve benchmark
  times which are large enough on modern systems.

* Cleanup of LFO APIs.

* Bumped version (2.1.1.svn18).

1 schoenebeck 3612 /*
2     Sine wave generator benchmark
3    
4     This is a benchmark for comparison between a built-in sin() function call
5     solution, and a numeric complex number solution.
6    
7     Copyright (C) 2019 Christian Schoenebeck <cuse@users.sf.net>
8     */
9    
10     #include "lfobench.h"
11    
12     #include "../src/engines/common/LFOSine.h"
13     #include "../src/engines/common/SineLFO.h"
14    
15     // return value of this benchmark
16     // to indicate the best performing solution
17     #define SINE_BUILTIN_SOLUTION 40
18     #define SINE_NUMERIC_COMPLEX_NR_SOLUTION 41
19     #define INVALID_RESULT -1
20    
21     #if SIGNED
22     LFOSine<LFO::range_signed>* pSineLFO = NULL;
23     SineLFO<LFO::range_signed>* pSineLFOBuiltin = NULL;
24     #else // unsigned
25     LFOSine<LFO::range_unsigned>* pSineLFO = NULL;
26     SineLFO<LFO::range_unsigned>* pSineLFOBuiltin = NULL;
27     #endif
28    
29     double sine_complex_nr(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) {
30     // pro forma
31     pSineLFO->trigger(frequency, LFO::start_level_max, 0 /* max. internal depth */, 1200, true, (unsigned int) SAMPLING_RATE);
32     //pSineLFO->setPhase(0);
33     //pSineLFO->setFrequency(frequency*2, SAMPLING_RATE);
34    
35     clock_t stop_time;
36     clock_t start_time = clock();
37    
38     for (int run = 0; run < RUNS; run++) {
39     pSineLFO->updateByMIDICtrlValue(127); // pro forma
40     for (int i = 0; i < steps; ++i) {
41     //pSineLFO->updateByMIDICtrlValue(float(i)/float(steps)*127.f);
42     pDestinationBuffer[i] = pSineLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load
43     }
44     }
45    
46     stop_time = clock();
47     double elapsed_time = (stop_time - start_time) / (double(CLOCKS_PER_SEC) / 1000.0);
48     #if ! SILENT
49     printf("Numeric complex nr solution elapsed time: %.1f ms\n", elapsed_time);
50     #endif
51    
52     return elapsed_time;
53     }
54    
55     double sine_builtin(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) {
56     // pro forma
57     pSineLFOBuiltin->trigger(frequency, LFO::start_level_max, 0 /* max. internal depth */, 1200, true, (unsigned int) SAMPLING_RATE);
58     //pSineLFOBuiltin->setPhase(0);
59     //pSineLFOBuiltin->setFrequency(frequency*2, SAMPLING_RATE);
60    
61     clock_t stop_time;
62     clock_t start_time = clock();
63    
64     for (int run = 0; run < RUNS; run++) {
65     pSineLFOBuiltin->updateByMIDICtrlValue(127); // pro forma
66     for (int i = 0; i < steps; ++i) {
67     //pSineLFOBuiltin->updateByMIDICtrlValue(float(i)/float(steps)*127.f);
68     pDestinationBuffer[i] = pSineLFOBuiltin->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load
69     }
70     }
71    
72     stop_time = clock();
73     double elapsed_time = (stop_time - start_time) / (double(CLOCKS_PER_SEC) / 1000.0);
74     #if ! SILENT
75     printf("Built-in function solution elapsed time: %.1f ms\n", elapsed_time);
76     #endif
77    
78     return elapsed_time;
79     }
80    
81     int main() {
82     const int steps = STEPS;
83     const int sinusoidFrequency = 100; // Hz
84    
85     #if ! SILENT
86     printf("\n");
87     # if SIGNED
88     printf("Signed sine wave benchmark\n");
89     # else
90     printf("Unsigned sine wave benchmark\n");
91     # endif
92     printf("----------------------------------\n");
93     printf("\n");
94     #endif
95    
96     #if SIGNED
97     pSineLFO = new LFOSine<LFO::range_signed>(MAX);
98     pSineLFOBuiltin = new SineLFO<LFO::range_signed>(MAX);
99     #else // unsigned
100     pSineLFO = new LFOSine<LFO::range_unsigned>(MAX);
101     pSineLFOBuiltin = new SineLFO<LFO::range_unsigned>(MAX);
102     #endif
103    
104     // output buffer for the calculated sinusoid wave
105     smpl_t* pOutputBuffer = new smpl_t[steps];
106     // just an arbitrary amplitude envelope to simulate a bit higher memory bandwidth
107     float* pAmplitude = new float[steps];
108    
109     // pro forma - an arbitary amplitude envelope
110     for (int i = 0; i < steps; ++i)
111     pAmplitude[i] = (float) i / (float) steps;
112    
113     // going to store how long each solution took (in seconds)
114     std::vector<BenchRes> results;
115    
116    
117     results.push_back({
118     .algorithmID = SINE_BUILTIN_SOLUTION,
119     .algorithmName = "Built-in function",
120     .timeMSecs = sine_builtin(pOutputBuffer, pAmplitude, steps, sinusoidFrequency)
121     });
122     #if OUTPUT_AS_RAW_WAVE
123     output_as_raw_file("sine_builtin_fn.raw", pOutputBuffer, steps);
124     #endif
125    
126    
127     results.push_back({
128     .algorithmID = SINE_NUMERIC_COMPLEX_NR_SOLUTION,
129     .algorithmName = "Numeric complex nr",
130     .timeMSecs = sine_complex_nr(pOutputBuffer, pAmplitude, steps, sinusoidFrequency)
131     });
132     #if OUTPUT_AS_RAW_WAVE
133     output_as_raw_file("sine_numeric_complex_nr.raw", pOutputBuffer, steps);
134     #endif
135    
136    
137     #if ! SILENT
138     printf("\nOK, 2nd try\n\n");
139     #endif
140    
141    
142     results[0].timeMSecs += sine_builtin(pOutputBuffer, pAmplitude, steps, sinusoidFrequency);
143     results[1].timeMSecs += sine_complex_nr(pOutputBuffer, pAmplitude, steps, sinusoidFrequency);
144    
145    
146     if (pAmplitude) delete[] pAmplitude;
147     if (pOutputBuffer) delete[] pOutputBuffer;
148    
149     if (pSineLFO) delete pSineLFO;
150     if (pSineLFOBuiltin) delete pSineLFOBuiltin;
151    
152     sortResultsFirstToBeBest(results);
153     printResultSummary(results);
154    
155     return results[0].algorithmID; // return the winner's numeric algorithm ID
156     }

  ViewVC Help
Powered by ViewVC