97 lines
3.4 KiB
C++
Executable File
97 lines
3.4 KiB
C++
Executable File
#include "tonegen.h"
|
|
#include "audio.h"
|
|
#include <math.h>
|
|
|
|
Sint16 notes[64];
|
|
|
|
toneGen::toneGen() {
|
|
this->current_pos = 0;
|
|
|
|
this->note = 34;
|
|
this->instrument = CHIPTUNE_INSTRUMENT_NOISE;
|
|
this->volume = 15;
|
|
this->effect = CHIPTUNE_EFFECT_FADEOUT;
|
|
|
|
this->current_volume = this->nominal_volume = 1.0f;
|
|
|
|
for (int i=0; i<64; ++i) {
|
|
const float NOTE_FREQ = 440 * pow(1.059463094359, i-34);
|
|
notes[i] = 65536 / int(SAMPLES_PER_SECOND/NOTE_FREQ);
|
|
}
|
|
|
|
this->old_df = this->df = notes[this->note];
|
|
this->f = -AUDIO_FORMAT_MAX_VALUE;
|
|
}
|
|
|
|
void toneGen::setNoteLength(const int note_length) {
|
|
this->note_length = note_length;
|
|
}
|
|
|
|
void toneGen::setup(const uint8_t note, const uint8_t instrument, const uint8_t volume, const uint8_t effect) {
|
|
this->current_pos = 0;
|
|
|
|
this->note = note;
|
|
this->instrument = instrument;
|
|
this->volume = volume;
|
|
this->effect = effect;
|
|
|
|
this->nominal_volume = float(volume) / 15.0f;
|
|
this->current_volume = this->effect == CHIPTUNE_EFFECT_FADEIN ? 0.0f : this->nominal_volume;
|
|
|
|
this->old_df = this->df;
|
|
this->df = notes[this->note];
|
|
this->f = -AUDIO_FORMAT_MAX_VALUE * this->current_volume;
|
|
}
|
|
|
|
void toneGen::setup(const uint16_t tracker_note) {
|
|
setup(tracker_note >> 10, (tracker_note >> 8) & 0x03, (tracker_note >> 4) & 0x0F, tracker_note & 0x0F );
|
|
}
|
|
|
|
const int toneGen::getSamples(const int numSamples, Sint16 *buffer) {
|
|
const int actual_samples_generated = SDL_min(numSamples, this->note_length-this->current_pos);
|
|
|
|
for (int i=0; i<actual_samples_generated;++i) {
|
|
f += df;
|
|
|
|
switch (this->effect) {
|
|
case CHIPTUNE_EFFECT_NONE:
|
|
break;
|
|
case CHIPTUNE_EFFECT_VIBRATO:
|
|
f += SDL_sinf((i+this->current_pos)/1000)*15;
|
|
break;
|
|
case CHIPTUNE_EFFECT_DROP:
|
|
if (((i+this->current_pos)%15)==0 && df != 0) { df--; if (df < 100) this->current_volume = this->nominal_volume*df*0.01f; }
|
|
if (df == 0) { buffer[i] = 0; continue; }
|
|
break;
|
|
case CHIPTUNE_EFFECT_FADEOUT:
|
|
if (this->current_volume > 0) this->current_volume -= (this->nominal_volume/float(this->note_length));
|
|
break;
|
|
case CHIPTUNE_EFFECT_FADEIN:
|
|
if (this->current_volume < this->nominal_volume) this->current_volume += (this->nominal_volume/float(this->note_length));
|
|
break;
|
|
}
|
|
|
|
buffer[i] = f;
|
|
|
|
Sint32 temp;
|
|
switch (this->instrument) {
|
|
case CHIPTUNE_INSTRUMENT_SAWTOOTH:
|
|
break;
|
|
case CHIPTUNE_INSTRUMENT_SQUARE:
|
|
buffer[i] = buffer[i] > 0 ? AUDIO_FORMAT_MAX_VALUE : -AUDIO_FORMAT_MAX_VALUE;
|
|
break;
|
|
case CHIPTUNE_INSTRUMENT_TRIANGLE:
|
|
temp = buffer[i];
|
|
buffer[i] = buffer[i] < 0 ? ((temp+AUDIO_FORMAT_MAX_VALUE)*2)-AUDIO_FORMAT_MAX_VALUE : (AUDIO_FORMAT_MAX_VALUE*2-temp*2)-AUDIO_FORMAT_MAX_VALUE;
|
|
break;
|
|
case CHIPTUNE_INSTRUMENT_NOISE:
|
|
buffer[i] = (rand()*2)-AUDIO_FORMAT_MAX_VALUE;
|
|
break;
|
|
}
|
|
buffer[i] *= this->current_volume;
|
|
}
|
|
|
|
this->current_pos += actual_samples_generated;
|
|
return actual_samples_generated;
|
|
}
|