Files
-
blinds / hardware_design / pcb / blinds_v60.brd
-
blinds / hardware_design / pcb / blinds_v60.sch
-
braids / hardware_design / pcb / braids_v50.brd
-
braids / hardware_design / pcb / braids_v50.sch
-
branches / hardware_design / pcb / branches_v40.brd
-
branches / hardware_design / pcb / branches_v40.sch
-
clouds / hardware_design / pcb / clouds_v30.brd
-
clouds / hardware_design / pcb / clouds_v30.sch
-
ears / hardware_design / panel / ears_panel_v30.brd
-
ears / hardware_design / panel / ears_panel_v30.sch
-
ears / hardware_design / pcb / ears_v40.brd
-
ears / hardware_design / pcb / ears_v40.sch
-
edges / hardware_design / pcb / edges_expander_v01.brd
-
edges / hardware_design / pcb / edges_expander_v01.sch
-
edges / hardware_design / pcb / edges_v20.brd
-
edges / hardware_design / pcb / edges_v20.sch
-
elements / hardware_design / pcb / elements_v02.brd
-
elements / hardware_design / pcb / elements_v02.sch
-
frames / hardware_design / pcb / frames_v03.brd
-
frames / hardware_design / pcb / frames_v03.sch
-
grids / hardware_design / pcb / grids_v02.brd
-
grids / hardware_design / pcb / grids_v02.sch
-
kinks / hardware_design / pcb / kinks_v41.brd
-
kinks / hardware_design / pcb / kinks_v41.sch
-
links / hardware_design / pcb / links_v40.brd
-
links / hardware_design / pcb / links_v40.sch
-
marbles / hardware_design / pcb / marbles_v70.brd
-
marbles / hardware_design / pcb / marbles_v70.sch
-
peaks / hardware_design / pcb / peaks_v30.brd
-
peaks / hardware_design / pcb / peaks_v30.sch
-
plaits / hardware_design / pcb / plaits_v50.brd
-
plaits / hardware_design / pcb / plaits_v50.sch
-
rings / hardware_design / pcb / rings_v30.brd
-
rings / hardware_design / pcb / rings_v30.sch
-
ripples / hardware_design / pcb / ripples_v40.brd
-
ripples / hardware_design / pcb / ripples_v40.sch
-
shades / hardware_design / pcb / shades_v30.brd
-
shades / hardware_design / pcb / shades_v30.sch
-
shelves / hardware_design / pcb / shelves_expander_v10.brd
-
shelves / hardware_design / pcb / shelves_expander_v10.sch
-
shelves / hardware_design / pcb / shelves_v05.brd
-
shelves / hardware_design / pcb / shelves_v05.sch
-
stages / hardware_design / pcb / stages_v70.brd
-
stages / hardware_design / pcb / stages_v70.sch
-
streams / hardware_design / pcb / streams_v02_bargraph.brd
-
streams / hardware_design / pcb / streams_v02_bargraph.sch
-
streams / hardware_design / pcb / streams_v05.brd
-
streams / hardware_design / pcb / streams_v05.sch
-
tides / hardware_design / pcb / tides_v40.brd
-
tides / hardware_design / pcb / tides_v40.sch
-
veils / hardware_design / pcb / veils_v40.brd
-
veils / hardware_design / pcb / veils_v40.sch
-
volts / hardware_design / pcb / volts_v01.brd
-
volts / hardware_design / pcb / volts_v01.sch
-
warps / hardware_design / pcb / warps_v30.brd
-
warps / hardware_design / pcb / warps_v30.sch
-
yarns / hardware_design / pcb / yarns_v03.brd
-
yarns / hardware_design / pcb / yarns_v03.sch
Last update 6 years 1 month
by
Olivier Gillet
Fileswarpstest | |
---|---|
.. | |
makefile | |
warps_test.cc |
warps_test.cc// Copyright 2014 Olivier Gillet. // // Author: Olivier Gillet (ol.gillet@gmail.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // See http://creativecommons.org/licenses/MIT/ for more information. // // ----------------------------------------------------------------------------- #include <cassert> #include <cmath> #include <cstdlib> #include <cstring> #include <vector> #include <xmmintrin.h> #include "stmlib/test/wav_writer.h" #include "stmlib/utils/random.h" #include "warps/dsp/modulator.h" #include "warps/dsp/sample_rate_converter.h" #include "warps/resources.h" using namespace warps; using namespace std; using namespace stmlib; const size_t kSampleRate = 96000; const size_t kBlockSize = 96; template<typename T> void TestSRCUp(const char* name) { size_t ratio = 6; WavWriter wav_writer(1, kSampleRate * ratio, 10); wav_writer.Open(name); T src_up; src_up.Init(); float phase = 0.0f; while (!wav_writer.done()) { float samples_in[kBlockSize]; float samples_out[kBlockSize * ratio]; float instantenous_frequency = fmod( 4.0f * wav_writer.progress(), 0.5f); for (size_t i = 0; i < kBlockSize; ++i) { samples_in[i] = sinf(phase * 2 * M_PI); phase += instantenous_frequency; if (phase >= 1.0f) { phase -= 1.0f; } } src_up.Process(samples_in, samples_out, kBlockSize); wav_writer.Write(samples_out, kBlockSize * ratio, 16067.0f); } } void TestSRC96To576To96() { size_t ratio = 6; WavWriter wav_writer(1, kSampleRate, 10); wav_writer.Open("warps_src_96_576_96.wav"); SampleRateConverter<SRC_UP, 6, 48> src_up; SampleRateConverter<SRC_DOWN, 6, 48> src_down; src_up.Init(); src_down.Init(); float phase = 0.0f; while (!wav_writer.done()) { float samples_in[kBlockSize]; float samples_out[kBlockSize * ratio]; float instantenous_frequency = fmod( 2.0f * wav_writer.progress(), 0.5f); for (size_t i = 0; i < kBlockSize; ++i) { samples_in[i] = sinf(phase * 2 * M_PI); phase += instantenous_frequency; if (phase >= 1.0f) { phase -= 1.0f; } } src_up.Process(samples_in, samples_out, kBlockSize); src_down.Process(samples_out, samples_in, kBlockSize * ratio); wav_writer.Write(samples_in, kBlockSize, 32200.0f); } } void TestModulator() { FILE* fp_in = fopen("audio_samples/modulation_96k.wav", "rb"); WavWriter wav_writer(2, kSampleRate, 15); wav_writer.Open("warps_modulator.wav"); fseek(fp_in, 48, SEEK_SET); Modulator modulator; modulator.Init(kSampleRate); Parameters* p = modulator.mutable_parameters(); float phi = 0.0f; float filtered_noise = 0.0f; while (!wav_writer.done()) { float triangle = wav_writer.triangle(); float square = 0.5f * SoftClip(32.0f * (triangle - 0.5f)) + 0.5f; float noise = (Random::GetFloat() - 0.5f) / 128.0f; filtered_noise += (noise - filtered_noise) * 0.1f; p->carrier_shape = 1; p->channel_drive[0] = 0.625f; p->channel_drive[1] = 0.0f; p->modulation_algorithm = 0.125f + 0.0f * square + 1.0f * filtered_noise; p->modulation_parameter = 0.0f + 1.0f * triangle; p->note = 48.0f + phi; ShortFrame input[kBlockSize]; ShortFrame output[kBlockSize]; if (fread( input, sizeof(ShortFrame), kBlockSize, fp_in) != kBlockSize) { break; } for (size_t i = 0; i < kBlockSize; ++i) { input[i].r = input[i].l; input[i].l = 0; } modulator.Process(input, output, kBlockSize); wav_writer.WriteFrames((short*)(output), kBlockSize); } fclose(fp_in); } void TestEasterEgg() { FILE* fp_in = fopen("audio_samples/modulation_96k.wav", "rb"); WavWriter wav_writer(2, kSampleRate, 15); wav_writer.Open("warps_easter_egg.wav"); fseek(fp_in, 48, SEEK_SET); Modulator modulator; modulator.Init(kSampleRate); modulator.set_easter_egg(true); Parameters* p = modulator.mutable_parameters(); float phi = 0.0f; float filtered_noise = 0.0f; while (!wav_writer.done()) { uint16_t tri = (wav_writer.remaining_frames() / 8); tri = tri > 32767 ? 65535 - tri : tri; float triangle = 0.5f * SoftClip(8.0f * (tri / 32768.0f - 0.5f)) + 0.5f; float square = 0.5f * SoftClip(32.0f * (tri / 32768.0f - 0.5f)) + 0.5f; float noise = (Random::GetFloat() - 0.5f) / 128.0f; filtered_noise += (noise - filtered_noise) * 0.1f; p->frequency_shift_pot = 0.85f + 0.0f * triangle + 0.0f * filtered_noise; p->frequency_shift_cv = 0.0f; p->carrier_shape = 1; p->channel_drive[0] = 0.0f; p->channel_drive[1] = 1.0f; p->modulation_parameter = 0.0f + 0.0f * square; p->note = 48.0f + phi; ShortFrame input[kBlockSize]; ShortFrame output[kBlockSize]; if (fread( input, sizeof(ShortFrame), kBlockSize, fp_in) != kBlockSize) { break; } for (size_t i = 0; i < kBlockSize; ++i) { input[i].r = input[i].l; input[i].l = 0; } modulator.Process(input, output, kBlockSize); wav_writer.WriteFrames((short*)(output), kBlockSize); } fclose(fp_in); } void TestOscillators() { WavWriter wav_writer(2, kSampleRate, 15); wav_writer.Open("warps_oscillator.wav"); Modulator modulator; modulator.Init(kSampleRate); Parameters* p = modulator.mutable_parameters(); p->carrier_shape = 3; p->channel_drive[0] = 0.0f; p->channel_drive[1] = 0.0f; p->modulation_algorithm = 0.0f; p->modulation_parameter = 0.0f; ShortFrame input[kBlockSize]; ShortFrame zero; zero.l = zero.r = 0.0f; fill(&input[0], &input[kBlockSize], zero); while (!wav_writer.done()) { float triangle = wav_writer.triangle(); p->note = 20 + triangle * 0; ShortFrame output[kBlockSize]; modulator.Process(input, output, kBlockSize); wav_writer.WriteFrames((short*)(output), kBlockSize); } } void TestFilterBankReconstruction() { FilterBank fb; fb.Init(96000.0); size_t num_blocks = 1000; const size_t block_size = 96; FILE* fp_out = fopen("warps_filterbank_ir_float32.bin", "wb"); float in[block_size]; float out[block_size]; for (size_t i = 0; i < num_blocks; ++i) { fill(&in[0], &in[block_size], 0.0f); if (i == 0) { in[0] = 1.0f; } fb.Analyze(in, block_size); for (int32_t j = 0; j < kNumBands; ++j) { if (false) { float* samples = fb.band(j).samples; size_t size = block_size / fb.band(j).decimation_factor; fill(&samples[0], &samples[size], 0.0f); } } fb.Synthesize(out, block_size); fwrite(out, sizeof(float), block_size, fp_out); } fclose(fp_out); // The impulse response and frequency responses can be seen with the following // python program: // // import numpy // import pylab // // x = numpy.fromfile('warps_filterbank_ir_float32.bin', dtype=numpy.float32) // pylab.subplot(211) // pylab.plot(x[:500]) // pylab.subplot(212) // xf = numpy.fft.rfft(x) // N = len(xf) // f = numpy.arange(0.0, N) / N * 48000 // pylab.semilogx(f, 20 * numpy.log10(numpy.abs(xf + 1e-8))) // pylab.show() } void TestSineTransition() { WavWriter wav_writer(2, kSampleRate, 15); wav_writer.Open("warps_sine_transition.wav"); Modulator modulator; modulator.Init(kSampleRate); Parameters* p = modulator.mutable_parameters(); while (!wav_writer.done()) { float triangle = wav_writer.triangle(); p->carrier_shape = 1; p->channel_drive[0] = 0.0; p->channel_drive[1] = 0.0f; p->modulation_algorithm = 0.0f + 0.125f * triangle; p->modulation_parameter = 0.0f; p->note = 36.0f; ShortFrame input[kBlockSize]; ShortFrame output[kBlockSize]; for (size_t i = 0; i < kBlockSize; ++i) { input[i].r = 0; input[i].l = 0; } modulator.Process(input, output, kBlockSize); wav_writer.WriteFrames((short*)output, kBlockSize); } } void TestGain() { WavWriter wav_writer(2, kSampleRate, 10); wav_writer.Open("warps_gain.wav"); Modulator modulator; modulator.Init(kSampleRate); Parameters* p = modulator.mutable_parameters(); float phase = 0.0f; while (!wav_writer.done()) { float triangle = wav_writer.triangle(); p->carrier_shape = 0; p->channel_drive[0] = triangle * 1.0f; p->channel_drive[1] = 0.0f; p->modulation_algorithm = 0.0f + 0.125f * 0.0f; p->modulation_parameter = 0.0f; p->note = 36.0f; ShortFrame input[kBlockSize]; ShortFrame output[kBlockSize]; for (size_t i = 0; i < kBlockSize; ++i) { input[i].l = 20480.0f * sinf(phase * 2 * M_PI); input[i].r = 20480.0f * sinf(phase * 2 * M_PI); phase += 220.0f / kSampleRate; if (phase >= 1.0f) { phase -= 1.0f; } } modulator.Process(input, output, kBlockSize); wav_writer.WriteFrames((short*)output, kBlockSize); } } void TestQuadratureOscillator() { WavWriter wav_writer(2, kSampleRate, 10); wav_writer.Open("warps_quadrature.wav"); QuadratureOscillator q; q.Init(kSampleRate); while (!wav_writer.done()) { float triangle = wav_writer.triangle(); float x[2]; q.Render(triangle, 100.8f, &x[0], &x[1], 1); wav_writer.Write(x, 2, 32767.0f); } } int main(void) { _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); TestSRCUp<SampleRateConverter<SRC_UP, 6, 48> >("warps_src_up_fir_48.wav"); TestSRC96To576To96(); // TestModulator(); // TestEasterEgg(); TestOscillators(); TestFilterBankReconstruction(); TestSineTransition(); TestGain(); TestQuadratureOscillator(); }