|
- // Copyright 2014 Olivier Gillet.
- //
- // Author: Olivier Gillet (ol.gillet@gmail.com)
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <xmmintrin.h>
-
- #include "elements/dsp/exciter.h"
- #include "elements/dsp/part.h"
- #include "elements/dsp/resonator.h"
- #include "elements/dsp/voice.h"
-
- using namespace elements;
- using namespace stmlib;
-
- const uint32_t kSampleRate = 32000;
- const uint16_t kAudioBlockSize = 32;
-
- void write_wav_header(FILE* fp, int num_samples, int num_channels) {
- uint32_t l;
- uint16_t s;
-
- fwrite("RIFF", 4, 1, fp);
- l = 36 + num_samples * 2 * num_channels;
- fwrite(&l, 4, 1, fp);
- fwrite("WAVE", 4, 1, fp);
-
- fwrite("fmt ", 4, 1, fp);
- l = 16;
- fwrite(&l, 4, 1, fp);
- s = 1;
- fwrite(&s, 2, 1, fp);
- s = num_channels;
- fwrite(&s, 2, 1, fp);
- l = ::kSampleRate;
- fwrite(&l, 4, 1, fp);
- l = static_cast<uint32_t>(::kSampleRate) * 2 * num_channels;
- fwrite(&l, 4, 1, fp);
- s = 2 * num_channels;
- fwrite(&s, 2, 1, fp);
- s = 16;
- fwrite(&s, 2, 1, fp);
-
- fwrite("data", 4, 1, fp);
- l = num_samples * 2 * num_channels;
- fwrite(&l, 4, 1, fp);
- }
-
- void TestResonator() {
- FILE* fp = fopen("elements_resonator.wav", "wb");
- write_wav_header(fp, ::kSampleRate * 40, 1);
-
- Resonator resonator;
- resonator.Init();
- resonator.set_frequency(110.0f / ::kSampleRate);
- resonator.set_geometry(0.2f);
- resonator.set_brightness(0.4f);
- resonator.set_damping(0.4f);
- resonator.set_position(0.5f);
- // resonator.set_resolution(1);
-
- float impulse = 1.0f;
- float noise_level = 0.0f;
- for (uint32_t i = 0; i < ::kSampleRate * 40; ++i) {
- uint16_t tri = (i / 2);
- tri = tri > 32767 ? 65535 - tri : tri;
- uint16_t tri2 = (i / 25);
- tri2 = tri2 > 32767 ? 65535 - tri2 : tri2;
-
- resonator.set_position(tri / 32768.0f);
-
- if (i % (::kSampleRate / 8) == 0 && (rand() % 8 > 2)) {
- float frequencies[5] = { 110.0f, 220.0f * powf(2, 3/12.0f), 220.0f, 880.0f, 55.0f };
- resonator.set_frequency(frequencies[rand() % 5] / ::kSampleRate);
- resonator.set_geometry((rand() % 32768) / 32768.0f);
- resonator.set_brightness((rand() % 32768) / 32768.0f);
- resonator.set_damping((rand() % 32768) / 32768.0f);
- noise_level = (rand() % 4) == 1 ? 1.0f : 0.0f;
- if (noise_level) {
- resonator.set_damping(0.7f);
- resonator.set_brightness((rand() % 32768) / 65535.0f);
- } else{
- impulse = 1.0f;
- }
- }
-
- impulse = impulse * 0.99f;
-
- float bow_strength = 0.0f;
- float output;
- float aux;
- float input = impulse;
- input += ((rand() % 32768) - 16384) / 65535.0f * noise_level;
- resonator.Process(&bow_strength, &input, &output, &aux, 1);
-
- output = output * 32768.0f;
- if (output > 32767) output = 32767;
- if (output < -32767) output = -32767;
- short output_sample = output;
- fwrite(&output_sample, sizeof(int16_t), 1, fp);
- }
- fclose(fp);
- }
-
- void TestExciter() {
- FILE* fp = fopen("elements_exciter.wav", "wb");
- write_wav_header(fp, ::kSampleRate * 10, 4);
-
- float diffuser_buffer[1024];
-
- Exciter exciter;
- exciter.Init();
- exciter.set_model(EXCITER_MODEL_PLECTRUM);
- exciter.set_parameter(0.7f);
- exciter.set_timbre(0.5f);
- exciter.set_signature(0.1f);
-
- Resonator resonator;
- resonator.Init();
- resonator.set_frequency(262.0f / ::kSampleRate / 2);
- resonator.set_geometry(0.3f);
- resonator.set_brightness(0.8f);
- resonator.set_damping(0.3f);
- resonator.set_position(0.1f);
- resonator.set_resolution(48);
-
- bool previous_gate = false;
- for (uint32_t i = 0; i < ::kSampleRate * 10; ++i) {
- uint16_t tri = (i / 8);
- tri = tri > 32767 ? 65535 - tri : tri;
-
- uint16_t tri2 = (i * 1.5);
- tri2 = tri2 > 32767 ? 65535 - tri2 : tri2;
-
- bool gate = (i % (::kSampleRate / 2)) < (::kSampleRate / 4);
-
- uint8_t flags = 0;
- if (gate) flags |= EXCITER_FLAG_GATE;
- if (gate && !previous_gate) flags |= EXCITER_FLAG_RISING_EDGE;
- if (!gate && previous_gate) flags |= EXCITER_FLAG_FALLING_EDGE;
- previous_gate = gate;
-
- exciter.set_parameter(tri / 32768.0f);
- // exciter.set_timbre(tri / 32768.0f);
-
- float bow_strength = 0.0f;
- float output[4];
- short output_sample[4];
- exciter.Process(flags, &output[0], 1);
- // output[0] *= 0.15;
- output[1] = exciter.damping();
- resonator.Process(&bow_strength, &output[0], &output[2], &output[3], 1);
- for (int j = 0; j < 4; ++j) {
- output[j] *= 32767.0f;
- if (output[j] > 32767) output[j] = 32767;
- if (output[j] < -32767) output[j] = -32767;
- output_sample[j] = output[j];
- }
- fwrite(output_sample, sizeof(int16_t), 4, fp);
- }
- fclose(fp);
- }
-
- void TestVoice() {
- FILE* fp = fopen("elements_voice.wav", "wb");
- write_wav_header(fp, ::kSampleRate * 20, 4);
-
- Voice voice;
- Patch p;
- p.exciter_envelope_shape = 0.95f;
- p.exciter_bow_level = 0.5f;
- p.exciter_bow_timbre = 0.6f;
- p.exciter_blow_level = 0.0f;
- p.exciter_blow_meta = 0.5f;
- p.exciter_blow_timbre = 0.2f;
- p.exciter_strike_level = 0.0f;
- p.exciter_strike_meta = 0.5f;
- p.exciter_strike_timbre = 0.5f;
- p.resonator_geometry = 0.2f;
- p.resonator_brightness = 0.9f;
- p.resonator_damping = 0.3f;
- p.resonator_position = 0.3f;
-
- voice.Init();
-
- for (uint32_t i = 0; i < ::kSampleRate * 20; ++i) {
- uint16_t tri = (i / 8);
- tri = tri > 32767 ? 65535 - tri : tri;
- p.resonator_damping = tri / 32768.0;
-
- bool gate = (i % (::kSampleRate * 4)) < (::kSampleRate * 2);
- float blow_in = 0.0f;
- float strike_in = 0.0f;
- float raw_out = 0.0f;
- float center = 0.0f;
- float sides = 0.0f;
-
- voice.Process(
- p,
- 262.0f / ::kSampleRate / 2.0f,
- 1.0f,
- gate,
- &blow_in,
- &strike_in,
- &raw_out,
- ¢er,
- &sides, 1);
-
- float output[4];
- short output_sample[4];
- output[0] = center + (sides) * 0.5f;
- output[1] = center - (sides) * 0.5f;
- output[2] = center;
- output[3] = raw_out;
-
- for (int j = 0; j < 4; ++j) {
- output[j] *= 32767.0f * (j != 3 ? 0.5f : 1.0f);
- if (output[j] > 32767) output[j] = 32767;
- if (output[j] < -32767) output[j] = -32767;
- output_sample[j] = output[j];
- }
- fwrite(output_sample, sizeof(int16_t), 4, fp);
- }
- fclose(fp);
- }
-
- void TestPart() {
- FILE* fp = fopen("elements_part.wav", "wb");
- write_wav_header(fp, ::kSampleRate * 20, 2);
-
- uint16_t reverb_buffer[32768];
- Part part;
- part.Init(reverb_buffer);
-
- Patch* p = part.mutable_patch();
-
- p->exciter_envelope_shape = 0.0f;
- p->exciter_bow_level = 0.0f;
- p->exciter_bow_timbre = 0.0f;
- p->exciter_blow_level = 0.0f;
- p->exciter_blow_meta = 0.0f;
- p->exciter_blow_timbre = 0.0f;
- p->exciter_strike_level = 0.5f;
- p->exciter_strike_meta = 0.5f;
- p->exciter_strike_timbre = 0.3f;
- p->resonator_geometry = 0.4f;
- p->resonator_brightness = 0.7f;
- p->resonator_damping = 0.8f;
- p->resonator_position = 0.3f;
- p->space = 0.1f;
-
-
- // p->exciter_envelope_shape = 0.99f;
- // p->exciter_bow_level = 0.0f;
- // p->exciter_bow_timbre = 0.6f;
- // p->exciter_blow_level = 0.0f;
- // p->exciter_blow_meta = 0.0f;
- // p->exciter_blow_timbre = 0.0f;
- // p->exciter_strike_level = 0.6f;
- // p->exciter_strike_meta = 0.5f;
- // p->exciter_strike_timbre = 0.5f;
- // p->resonator_geometry = 0.85f;
- // p->resonator_brightness = 1.0f;
- // p->resonator_damping = 0.6f;
- // p->resonator_position = 0.3f;
- // p->space = 0.1f;
-
- // p->exciter_envelope_shape = 0.0f;
- // p->exciter_bow_level = 0.0f;
- // p->exciter_bow_timbre = 0.5f;
- // p->exciter_blow_level = 0.0f;
- // p->exciter_blow_meta = 0.0f;
- // p->exciter_blow_timbre = 0.5f;
- // p->exciter_strike_level = 1.0f;
- // p->exciter_strike_meta = 0.2f;
- // p->exciter_strike_timbre = 0.6f;
- // p->resonator_geometry = 0.25f;
- // p->resonator_brightness = 0.3f;
- // p->resonator_damping = 0.5f;
- // p->resonator_position = 0.4f;
- // p->space = 1.0;
-
- // p->exciter_envelope_shape = 0.99f;
- // p->exciter_bow_level = 0.6f;
- // p->exciter_bow_timbre = 0.6f;
- // p->exciter_blow_level = 0.0f;
- // p->exciter_blow_meta = 0.0f;
- // p->exciter_blow_timbre = 0.0f;
- // p->exciter_strike_level = 0.0f;
- // p->exciter_strike_meta = 0.0f;
- // p->exciter_strike_timbre = 0.0f;
- // p->resonator_geometry = 0.25f;
- // p->resonator_brightness = 0.8f;
- // p->resonator_damping = 0.3f;
- // p->resonator_position = 0.3f;
- // p->space = 0.9f;
-
- float sequence[] = { 69.0f, 57.0f, 45.0f, 57.0f, 69.0f };
- // float sequence[] = { 19, 19, 19, 19, 19 };
- int sequence_counter = -1;
-
- float silence[16];
- std::fill(&silence[0], &silence[16], 0.0f);
-
- for (uint32_t i = 0; i < ::kSampleRate * 20; i += 16) {
- uint16_t tri = (i * 1);
- tri = tri > 32767 ? 65535 - tri : tri;
-
- uint16_t tri2 = (i / 6);
- tri2 = tri2 > 32767 ? 65535 - tri2 : tri2;
-
- float main[16];
- float aux[16];
-
- // p->resonator_position = int(256.0f * tri / 32768.0f) / 256.0f;
- // p->resonator_geometry = 0.5f + 0.5f * tri / 32768.0f;
-
- //p->exciter_strike_meta = 0.0f + 1.0f * tri / 32768.0f;
-
-
- if (i % (::kSampleRate * 2) == 0) {
- sequence_counter = (sequence_counter + 1) % 5;
- }
-
- PerformanceState performance;
- performance.note = sequence[sequence_counter] - 12.0f;
- performance.modulation = 0.0f; /*i & 16 ? 60.0f : -60.0f;
- if (i > ::kSampleRate * 5) {
- performance.modulation = 0;
- }*/
- performance.strength = 0.5f;
- performance.gate = (i % (::kSampleRate / 1)) < (::kSampleRate / 2);
-
- part.Process(performance, silence, silence, main, aux, 16);
-
- for (size_t j = 0; j < 16; ++j) {
- float output[2];
- short output_sample[2];
- output[0] = main[j];
- output[1] = aux[j];
-
- for (int k = 0; k < 2; ++k) {
- output[k] *= 32767.0f;
- if (output[k] > 32767) output[k] = 32767;
- if (output[k] < -32767) output[k] = -32767;
- output_sample[k] = output[k];
- }
- fwrite(output_sample, sizeof(int16_t), 2, fp);
- }
- }
- fclose(fp);
- }
-
-
- void TestEasterEgg() {
- FILE* fp = fopen("elements_easter_egg.wav", "wb");
- write_wav_header(fp, ::kSampleRate * 20, 2);
-
- uint16_t reverb_buffer[32768];
- Part part;
- part.Init(reverb_buffer);
-
- Patch* p = part.mutable_patch();
-
- part.set_easter_egg(true);
-
- // p->exciter_envelope_shape = 1.0f;
- // p->exciter_bow_level = 0.0f;
- // p->exciter_bow_timbre = 1.0f;
- // p->exciter_blow_level = 0.0f;
- // p->exciter_blow_meta = 0.27f;
- // p->exciter_blow_timbre = 0.3f;
- // p->exciter_strike_level = 1.0f;
- // p->exciter_strike_meta = 0.5f;
- // p->exciter_strike_timbre = 0.8f;
- // p->resonator_geometry = 0.3f;
- // p->resonator_brightness = 0.2f;
- // p->resonator_damping = 0.9f;
- // p->resonator_position = 0.0f;
- // p->space = 0.5f;
-
- p->exciter_envelope_shape = 0.2f;
- p->exciter_bow_level = 0.52f;
- p->exciter_bow_timbre = 0.8f;
-
- p->exciter_blow_level = 0.5f;
- p->exciter_blow_meta = 0.5f;
- p->exciter_blow_timbre = 0.0f;
-
- p->exciter_strike_level = 0.0f;
- p->exciter_strike_meta = 0.83f;
- p->exciter_strike_timbre = 0.5f;
-
- p->resonator_geometry = 0.0f;
- p->resonator_brightness = 1.0f;
- p->resonator_damping = 0.0f;
- p->resonator_position = 0.0f;
- p->space = 0.2f;
-
- float sequence[] = { 69.0f, 57.0f, 45.0f, 57.0f, 55.0f };
- int sequence_counter = -1;
-
- float silence[16];
- std::fill(&silence[0], &silence[16], 0.0f);
-
- for (uint32_t i = 0; i < ::kSampleRate * 20; i += 16) {
- uint16_t tri = (i / 2);
- tri = tri > 32767 ? 65535 - tri : tri;
-
- uint16_t tri2 = (i * 3);
- tri2 = tri2 > 32767 ? 65535 - tri2 : tri2;
-
- float main[16];
- float aux[16];
-
- // p->exciter_blow_meta = 0.5f + 0.5f * (tri / 32768.0f);
- // p->resonator_brightness = 0.0f + 1.0f * tri2 / 32768.0f;
- // p->resonator_position = 0.0f + 0.3f * tri / 32768.0f;
- // p->resonator_brightness = 0.0f + 1.0f * tri2 / 32768.0f;
-
- if (i % (::kSampleRate / 2) == 0) {
- sequence_counter = (sequence_counter + 1) % 5;
- }
-
- PerformanceState performance;
- //performance.note = sequence[sequence_counter] - 12;
- performance.note = 96.0f + (tri / 32768.0f) * 48.0;
- performance.modulation = 0.0f;
- performance.strength = 1.0f;
- performance.gate = true; // (i % (::kSampleRate / 2)) < (::kSampleRate / 4);
-
- part.Process(performance, silence, silence, main, aux, 16);
-
- for (size_t j = 0; j < 16; ++j) {
- float output[2];
- short output_sample[2];
- output[0] = main[j];
- output[1] = aux[j];
-
- for (int k = 0; k < 2; ++k) {
- output[k] *= 32767.0f;
- if (output[k] > 32767) output[k] = 32767;
- if (output[k] < -32767) output[k] = -32767;
- output_sample[k] = output[k];
- }
- fwrite(output_sample, sizeof(int16_t), 2, fp);
- }
- }
- fclose(fp);
- }
-
- void TestFilterAccuracy() {
- Svf f;
-
- for (int i = 0; i < 128; ++i) {
- float midi_note = i / 1.0f;
- float frequency = 440.0f * powf(2.0f, (midi_note - 69.0f) / 12.0f);
- frequency /= ::kSampleRate;
-
- float g[4];
- f.set_f_q<FREQUENCY_EXACT>(frequency, 0.5f);
- g[0] = f.g();
- f.set_f_q<FREQUENCY_ACCURATE>(frequency, 0.5f);
- g[1] = f.g();
- f.set_f_q<FREQUENCY_FAST>(frequency, 0.5f);
- g[2] = f.g();
- f.set_f_q<FREQUENCY_DIRTY>(frequency, 0.5f);
- g[3] = f.g();
-
- printf("Frequency: %f", frequency * ::kSampleRate);
- for (int j = 0; j < 4; ++j) {
- float error_cts = logf(atanf(g[j]) / M_PI / frequency) / logf(2) * 1200;
- printf("\t%.2f", error_cts);
- }
- printf("\n");
- }
- }
-
-
- int main(void) {
- _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
- // TestFilterAccuracy();
- TestPart();
- // TestExciter();
- // TestResonator();
- // TestEasterEgg();
- }
|