Files
chirping/tonegen.cpp

107 lines
3.6 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 = 0;
this->effect = CHIPTUNE_EFFECT_FADEOUT;
this->muted = false;
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;
this->vibrato_counter = 0;
}
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;
if (note == 0) return;
this->note = note;
this->instrument = instrument;
this->volume = volume;
this->effect = effect;
//this->muted = false;
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;
vibrato_counter += 0.001f;
switch (this->effect) {
case CHIPTUNE_EFFECT_NONE:
break;
case CHIPTUNE_EFFECT_VIBRATO:
f += SDL_sinf(vibrato_counter)*8;
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] *= (muted ? 0 : this->current_volume);
}
this->current_pos += actual_samples_generated;
return actual_samples_generated;
}
void toneGen::setMute(const bool value) {
muted = value;
}