RISC-V/V003/midi/tone.cpp

71 lines
1.7 KiB
C++
Raw Permalink Normal View History

2024-03-09 11:10:52 +01:00
#include "tone.h"
/**
* Přidán attack - zmizí rušivé lupání, prodlouží se obsluha tónu.
* */
extern "C" const short onePeriod[];
extern "C" const unsigned int midiTones[];
extern "C" const unsigned int attackTable[];
static constexpr unsigned defFall = 16u;
static constexpr unsigned maxAttack = 127u;
Tone::Tone() noexcept {
ampl = 0; freq = 0; base = 0; atck = 0;
fall = defFall;
}
void Tone::setAmpl (unsigned int a) {
ampl = a;
}
void Tone::setFreq (unsigned int f) {
freq = f;
}
void Tone::setMidiOn (unsigned int m) {
freq = midiTones [m & 0x7F];
if (freq) atck = maxAttack;
fall = 1;
}
void Tone::setMidiOff (void) {
fall = defFall;
/*
base = 0;
freq = 0;
*/
}
void Tone::setFall (unsigned int f) {
fall = f;
}
int Tone::step (void) {
unsigned int k,t;
int y;
// Spočteme index x pro přístup do tabulky
const unsigned x = (base >> 16) & 0xFF;
y = onePeriod [x]; // vzorek vezmeme z tabulky
// k je horní půlka amplitudy
k = ampl >> 16;
y *= k; // vzorek násobíme amplitudou (tedy tím vrškem)
y >>= 12; // a vezmeme jen to, co potřebuje DAC
k *= fall; // Konstanta fall určuje rychlost poklesu amplitudy,
// čím více, tím je rychlejší. Pokud by bylo 1, pokles je 2^16 vzorků, což už je pomalé.
base += freq; // časová základna pro další vzorek
if (atck) { // přidán attack = náběh amplitudy
t = attackTable [atck]; // z tabulky
if (t > ampl) ampl = t; // prevence lupání - nemí být skok amplitudy
atck -= 1; // dočasovat k nule
} else
ampl -= k; // exponenciální pokles amplitudy
// a je to
return y;
}