Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
206070834This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright 2014 Olivier Gillet.
// Copyright 2016 Tim Churches
//
// Original Author: Olivier Gillet (ol.gillet@gmail.com)
// Modifications for use of this code in firmare for the Ornament and Crime module:
// Tim Churches (tim.churches@gmail.com)
//
// Idea for using Rössler generator attributable to Hotlblack Desiato
// (see http://forbinthesynthesizer.blogspot.com.au/2015/11/rossler-barrow.html)
//
// 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.
//
// -----------------------------------------------------------------------------
//
// Lorenz and Rössler systems.
#include "streams_lorenz_generator.h"
#include "streams_resources.h"
namespace streams {
// using namespace stmlib;
const int64_t sigma = 10.0 * (1 << 24);
//const int64_t rho = 28.0 * (1 << 24);
const int64_t beta = 8.0 / 3.0 * (1 << 24);
// Rossler constants
const int64_t a = 0.1 * (1 << 24);
const int64_t b = 0.1 * (1 << 24);
// const int64_t c = 13.0 * (1 << 24);
void LorenzGenerator::Init(uint8_t index) {
if (index) {
Lx2_ = 0.1 * (1 << 24);
Ly2_ = 0;
Lz2_ = 0;
Rx2_ = 0.1 * (1 << 24);
Ry2_ = 0;
Rz2_ = 0;
} else {
Lx1_ = 0.1 * (1 << 24);
Ly1_ = 0;
Lz1_ = 0;
Rx1_ = 0.1 * (1 << 24);
Ry1_ = 0;
Rz1_ = 0;
}
}
void LorenzGenerator::Process(
int32_t freq1,
int32_t freq2,
bool reset1,
bool reset2,
uint8_t freq_range1,
uint8_t freq_range2) {
int32_t rate1 = (freq1 >> 8);
if (rate1 < 0) rate1 = 0;
if (rate1 > 255) rate1 = 255;
int32_t rate2 = (freq2 >> 8);
if (rate2 < 0) rate2 = 0;
if (rate2 > 255) rate2 = 255;
if (reset1) Init(0) ;
if (reset2) Init(1) ;
// yes, yes, these should be functions...
// Lorenz 1
int64_t Ldt1 = static_cast<int64_t>(lut_lorenz_rate[rate1] >> (5 - freq_range1)); // was 5
int32_t Lx1 = Lx1_ + (Ldt1 * ((sigma * (Ly1_ - Lx1_)) >> 24) >> 24);
int32_t Ly1 = Ly1_ + (Ldt1 * ((Lx1_ * (rho1_ - Lz1_) >> 24) - Ly1_) >> 24);
int32_t Lz1 = Lz1_ + (Ldt1 * ((Lx1_ * int64_t(Ly1_) >> 24) - (beta * Lz1_ >> 24)) >> 24);
Lx1_ = Lx1;
Ly1_ = Ly1;
Lz1_ = Lz1;
int32_t Lz1_scaled = ((Lz1 * 3) >> 16);
int32_t Lx1_scaled = ((Lx1 * 3) >> 16) + 32769;
int32_t Ly1_scaled = ((Ly1 * 3) >> 16) + 32769;
// Rossler 1
int64_t Rdt1 = static_cast<int64_t>(lut_lorenz_rate[rate1] >> 0);
int32_t Rx1 = Rx1_ + ((Rdt1 * (-Ry1_ - Rz1_ )) >> 24);
int32_t Ry1 = Ry1_ + ((Rdt1 * (Rx1_ + ((a * Ry1_) >> 24))) >> 24);
int32_t Rz1 = Rz1_ + ((Rdt1 * (b + ((Rz1_ * (Rx1_ - c1_)) >> 24))) >> 24);
Rx1_ = Rx1;
Ry1_ = Ry1;
Rz1_ = Rz1;
int32_t Rz1_scaled = (Rz1 >> 14);
int32_t Rx1_scaled = (Rx1 >> 14) + 32769;
int32_t Ry1_scaled = (Ry1 >> 14) + 32769;
// Lorenz 2
int64_t Ldt2 = static_cast<int64_t>(lut_lorenz_rate[rate2] >> (5 - freq_range2)); // was 5
int32_t Lx2 = Lx2_ + (Ldt2 * ((sigma * (Ly2_ - Lx2_)) >> 24) >> 24);
int32_t Ly2 = Ly2_ + (Ldt2 * ((Lx2_ * (rho2_ - Lz2_) >> 24) - Ly2_) >> 24);
int32_t Lz2 = Lz2_ + (Ldt2 * ((Lx2_ * int64_t(Ly2_) >> 24) - (beta * Lz2_ >> 24)) >> 24);
Lx2_ = Lx2;
Ly2_ = Ly2;
Lz2_ = Lz2;
int32_t Lz2_scaled = ((Lz2 * 3) >> 16);
int32_t Lx2_scaled = ((Lx2 * 3) >> 16) + 32769;
int32_t Ly2_scaled = ((Ly2 * 3) >> 16) + 32769;
// Rossler 2
int64_t Rdt2 = static_cast<int64_t>(lut_lorenz_rate[rate2] >> 0);
int32_t Rx2 = Rx2_ + ((Rdt2 * (-Ry2_ - Rz2_ )) >> 24);
int32_t Ry2 = Ry2_ + ((Rdt2 * (Rx2_ + ((a * Ry2_) >> 24))) >> 24);
int32_t Rz2 = Rz2_ + ((Rdt2 * (b + ((Rz2_ * (Rx2_ - c2_)) >> 24))) >> 24);
Rx2_ = Rx2;
Ry2_ = Ry2;
Rz2_ = Rz2;
int32_t Rz2_scaled = (Rz2 >> 14);
int32_t Rx2_scaled = (Rx2 >> 14) + 32769;
int32_t Ry2_scaled = (Ry2 >> 14) + 32769;
uint8_t out_channel ;
for (uint8_t i = 0; i < 4; ++i) {
switch(i) {
case 0:
out_channel = out_a_ ;
break ;
case 1:
out_channel = out_b_ ;
break ;
case 2:
out_channel = out_c_ ;
break ;
case 3:
out_channel = out_d_ ;
break ;
default:
// shut up compiler warning: 'out_channel' may be used uninitialized
out_channel = LORENZ_OUTPUT_LAST;
break ;
}
switch (out_channel) {
case LORENZ_OUTPUT_X1:
dac_code_[i] = Lx1_scaled;
break;
case LORENZ_OUTPUT_Y1:
dac_code_[i] = Ly1_scaled;
break;
case LORENZ_OUTPUT_Z1:
dac_code_[i] = Lz1_scaled;
break;
case LORENZ_OUTPUT_X2:
dac_code_[i] = Lx2_scaled;
break;
case LORENZ_OUTPUT_Y2:
dac_code_[i] = Ly2_scaled;
break;
case LORENZ_OUTPUT_Z2:
dac_code_[i] = Lz2_scaled;
break;
case ROSSLER_OUTPUT_X1:
dac_code_[i] = Rx1_scaled;
break;
case ROSSLER_OUTPUT_Y1:
dac_code_[i] = Ry1_scaled;
break;
case ROSSLER_OUTPUT_Z1:
dac_code_[i] = Rz1_scaled;
break;
case ROSSLER_OUTPUT_X2:
dac_code_[i] = Rx2_scaled;
break;
case ROSSLER_OUTPUT_Y2:
dac_code_[i] = Ry2_scaled;
break;
case ROSSLER_OUTPUT_Z2:
dac_code_[i] = Rz2_scaled;
break;
case LORENZ_OUTPUT_LX1_PLUS_RX1:
dac_code_[i] = (Lx1_scaled + Rx1_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_PLUS_RZ1:
dac_code_[i] = (Lx1_scaled + Rz1_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_PLUS_LY2:
dac_code_[i] = (Lx1_scaled + Ly2_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_PLUS_LZ2:
dac_code_[i] = (Lx1_scaled + Lz2_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_PLUS_RX2:
dac_code_[i] = (Lx1_scaled + Rx2_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_PLUS_RZ2:
dac_code_[i] = (Lx1_scaled + Rz2_scaled) >> 1;
break;
case LORENZ_OUTPUT_LX1_XOR_LY1:
dac_code_[i] = Lx1_scaled ^ Ly1_scaled ;
break;
case LORENZ_OUTPUT_LX1_XOR_LX2:
dac_code_[i] = Lx1_scaled ^ Lx2_scaled ;
break;
case LORENZ_OUTPUT_LX1_XOR_RX1:
dac_code_[i] = Lx1_scaled ^ Rx1_scaled ;
break;
case LORENZ_OUTPUT_LX1_XOR_RX2:
dac_code_[i] = Lx1_scaled ^ Rx2_scaled ;
break;
default:
break;
}
}
}
} // namespace streams