#include "tonegen.h" #include "audio.h" #include 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; ieffect) { 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; }