Player: volume depend of frequency

higher the note is, lower is the volume.
This commit is contained in:
Louis-Joseph Fournier 2016-01-14 22:03:36 +01:00
parent 8178009eb5
commit 606eb1c8e7
2 changed files with 37 additions and 4 deletions

View file

@ -21,6 +21,14 @@
#include "FreqPlayer.hpp" #include "FreqPlayer.hpp"
#ifndef min
#define min(a,b) (a<b?a:b)
#endif
#ifndef max
#define max(a,b) (a>b?a:b)
#endif
template<typename sample_t> FreqPlayer<sample_t>::FreqPlayer(int _rate): template<typename sample_t> FreqPlayer<sample_t>::FreqPlayer(int _rate):
rate(_rate), rate(_rate),
n_frame(0) n_frame(0)
@ -28,6 +36,7 @@ template<typename sample_t> FreqPlayer<sample_t>::FreqPlayer(int _rate):
k = K(); k = K();
k_update = -1; // invalid: don't update k_update = -1; // invalid: don't update
max_harmonic_freq = rate / 2; max_harmonic_freq = rate / 2;
freq2volume();
} }
template<typename sample_t> void FreqPlayer<sample_t>::Reset() template<typename sample_t> void FreqPlayer<sample_t>::Reset()
@ -37,6 +46,7 @@ template<typename sample_t> void FreqPlayer<sample_t>::Reset()
if (k_update != -1) { if (k_update != -1) {
k = k_update; k = k_update;
k_update = -1; k_update = -1;
freq2volume();
} }
} }
@ -62,8 +72,11 @@ template<typename sample_t> void FreqPlayer<sample_t>::SetWaveform(WAVEFORM form
waveform = form; waveform = form;
} }
template<> int16_t FreqPlayer<int16_t>::max() { return INT16_MAX; } template<> int16_t FreqPlayer<int16_t>::sample_min() { return INT16_MIN; }
template<> double FreqPlayer<double>::max() { return 1; } template<> double FreqPlayer<double>::sample_min() { return -1; }
template<> int16_t FreqPlayer<int16_t>::sample_max() { return INT16_MAX; }
template<> double FreqPlayer<double>::sample_max() { return 1; }
template<typename sample_t> double FreqPlayer<sample_t>::radius() template<typename sample_t> double FreqPlayer<sample_t>::radius()
{ {
@ -102,7 +115,13 @@ template<typename sample_t> sample_t FreqPlayer<sample_t>::AudioFrame()
break; break;
} }
return v * max() * volume; return max(min(v * sample_max() * volume, sample_max()), sample_min());
}
template<typename sample_t> void FreqPlayer<sample_t>::freq2volume()
{
if (volume_adaptative) volume = min(volume_max, max(volume_min, (freq_volume_min - freq) / (freq_volume_min - freq_volume_max) * (volume_max - volume_min) + volume_min));
std::cerr << "volume " << volume << std::endl;
} }
template<typename sample_t> void FreqPlayer<sample_t>::WriteAudio(sample_t *out, int nb_frame, bool stop) template<typename sample_t> void FreqPlayer<sample_t>::WriteAudio(sample_t *out, int nb_frame, bool stop)
@ -119,6 +138,7 @@ template<typename sample_t> void FreqPlayer<sample_t>::WriteAudio(sample_t *out,
n_frame = 0; n_frame = 0;
k = k_update; k = k_update;
k_update = -1; k_update = -1;
freq2volume();
v = AudioFrame(); v = AudioFrame();
} }
else if (stop) { else if (stop) {

View file

@ -30,10 +30,19 @@ template<typename sample_t> class FreqPlayer {
enum WAVEFORM { W_SINUS, W_TRIANGLE, W_HARMONIC }; enum WAVEFORM { W_SINUS, W_TRIANGLE, W_HARMONIC };
private: private:
/// frequencies for min and max volumes
static constexpr double freq_volume_min = 1200;
static constexpr double freq_volume_max = 120;
/// current frequency /// current frequency
double freq = 440; double freq = 440;
/// current volume (linear) /// current volume (linear)
double volume = 0.5; double volume = 0.5;
/// volume min and max
double volume_min = 0.5;
double volume_max = 1;
/// if volume is adaptative to freq (lower -> volume higher)
bool volume_adaptative = true;
/// audio rate /// audio rate
int rate; int rate;
/// current frame nb /// current frame nb
@ -52,9 +61,13 @@ template<typename sample_t> class FreqPlayer {
/// return k computed /// return k computed
double K() const; double K() const;
/// return the max sample_t /// return the max sample_t
sample_t max(); sample_t sample_min();
/// return the max sample_t
sample_t sample_max();
/// return the current radius /// return the current radius
double radius(); double radius();
/// return volume if adaptative
void freq2volume();
public: public:
FreqPlayer(int rate); FreqPlayer(int rate);