4 |
This is a benchmark for comparison between a integer math, table lookup |
This is a benchmark for comparison between a integer math, table lookup |
5 |
and numeric sine wave harmonics solution. |
and numeric sine wave harmonics solution. |
6 |
|
|
7 |
Copyright (C) 2005 Christian Schoenebeck <cuse@users.sf.net> |
Copyright (C) 2005 - 2017 Christian Schoenebeck <cuse@users.sf.net> |
8 |
*/ |
*/ |
9 |
|
|
10 |
#include <math.h> |
#include <math.h> |
24 |
// you can e.g. open it as RAW file in Rezound |
// you can e.g. open it as RAW file in Rezound |
25 |
// (32 bit SP-FP PCM, mono, little endian, 44100kHz) |
// (32 bit SP-FP PCM, mono, little endian, 44100kHz) |
26 |
#ifndef OUTPUT_AS_RAW_WAVE |
#ifndef OUTPUT_AS_RAW_WAVE |
27 |
# define OUTPUT_AS_RAW_WAVE 1 |
# define OUTPUT_AS_RAW_WAVE 0 |
28 |
#endif |
#endif |
29 |
|
|
30 |
// how many sample points should we calculate in one sequence |
// how many sample points should we calculate in one sequence |
61 |
#define INVALID_RESULT -1 |
#define INVALID_RESULT -1 |
62 |
|
|
63 |
// we use 32 bit single precision floating point as sample point format |
// we use 32 bit single precision floating point as sample point format |
64 |
typedef float sample_t; |
typedef float smpl_t; // (sample_t is already defined as int16_t by global_private.h) |
65 |
|
|
66 |
using namespace LinuxSampler; |
using namespace LinuxSampler; |
67 |
|
|
76 |
#endif |
#endif |
77 |
|
|
78 |
// integer math solution |
// integer math solution |
79 |
float int_math(sample_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
float int_math(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
80 |
// pro forma |
// pro forma |
81 |
pIntLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
pIntLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
82 |
|
|
84 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
85 |
|
|
86 |
for (int run = 0; run < RUNS; run++) { |
for (int run = 0; run < RUNS; run++) { |
87 |
pIntLFO->update(0); // pro forma |
pIntLFO->updateByMIDICtrlValue(127); // pro forma |
88 |
for (int i = 0; i < steps; ++i) { |
for (int i = 0; i < steps; ++i) { |
89 |
pDestinationBuffer[i] = pIntLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
pDestinationBuffer[i] = pIntLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
90 |
} |
} |
100 |
} |
} |
101 |
|
|
102 |
// integer math abs solution |
// integer math abs solution |
103 |
float int_math_abs(sample_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
float int_math_abs(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
104 |
// pro forma |
// pro forma |
105 |
pIntAbsLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
pIntAbsLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
106 |
|
|
108 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
109 |
|
|
110 |
for (int run = 0; run < RUNS; run++) { |
for (int run = 0; run < RUNS; run++) { |
111 |
pIntAbsLFO->update(0); // pro forma |
pIntAbsLFO->updateByMIDICtrlValue(0); // pro forma |
112 |
for (int i = 0; i < steps; ++i) { |
for (int i = 0; i < steps; ++i) { |
113 |
pDestinationBuffer[i] = pIntAbsLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
pDestinationBuffer[i] = pIntAbsLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
114 |
} |
} |
131 |
// anyway. If you found an architecture where this seems to be the best |
// anyway. If you found an architecture where this seems to be the best |
132 |
// solution, please let us know! |
// solution, please let us know! |
133 |
#if 0 |
#if 0 |
134 |
float table_lookup(sample_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
float table_lookup(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
135 |
// pro forma |
// pro forma |
136 |
const float r = frequency / SAMPLING_RATE; // frequency alteration quotient |
const float r = frequency / SAMPLING_RATE; // frequency alteration quotient |
137 |
#if SIGNED |
#if SIGNED |
194 |
#endif |
#endif |
195 |
|
|
196 |
// numeric, di-harmonic solution |
// numeric, di-harmonic solution |
197 |
float numeric_di_harmonic_solution(sample_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
float numeric_di_harmonic_solution(smpl_t* pDestinationBuffer, float* pAmp, const int steps, const float frequency) { |
198 |
// pro forma |
// pro forma |
199 |
pDiHarmonicLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
pDiHarmonicLFO->trigger(frequency, start_level_max, 1200 /* max. internal depth */, 0, false, (unsigned int) SAMPLING_RATE); |
200 |
|
|
202 |
clock_t start_time = clock(); |
clock_t start_time = clock(); |
203 |
|
|
204 |
for (int run = 0; run < RUNS; run++) { |
for (int run = 0; run < RUNS; run++) { |
205 |
pDiHarmonicLFO->update(0); // pro forma |
pDiHarmonicLFO->updateByMIDICtrlValue(127); // pro forma |
206 |
for (int i = 0; i < steps; ++i) { |
for (int i = 0; i < steps; ++i) { |
207 |
pDestinationBuffer[i] = pDiHarmonicLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
pDestinationBuffer[i] = pDiHarmonicLFO->render() * pAmp[i]; // * pAmp[i] just to simulate some memory load |
208 |
} |
} |
218 |
} |
} |
219 |
|
|
220 |
// output calculated values as RAW audio format (32 bit floating point, mono) file |
// output calculated values as RAW audio format (32 bit floating point, mono) file |
221 |
void output_as_raw_file(const char* filename, sample_t* pOutputBuffer, int steps) { |
void output_as_raw_file(const char* filename, smpl_t* pOutputBuffer, int steps) { |
222 |
FILE* file = fopen(filename, "w"); |
FILE* file = fopen(filename, "w"); |
223 |
if (file) { |
if (file) { |
224 |
fwrite((void*) pOutputBuffer, sizeof(float), steps, file); |
fwrite((void*) pOutputBuffer, sizeof(float), steps, file); |
253 |
#endif |
#endif |
254 |
|
|
255 |
// output buffer for the calculated sinusoid wave |
// output buffer for the calculated sinusoid wave |
256 |
sample_t* pOutputBuffer = new sample_t[steps]; |
smpl_t* pOutputBuffer = new smpl_t[steps]; |
257 |
// just an arbitrary amplitude envelope to simulate a bit higher memory bandwidth |
// just an arbitrary amplitude envelope to simulate a bit higher memory bandwidth |
258 |
float* pAmplitude = new float[steps]; |
float* pAmplitude = new float[steps]; |
259 |
|
|