mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-26 22:43:01 +00:00
reduce CPU usage massively
This commit is contained in:
parent
17f4cab32d
commit
509d20c215
3 changed files with 70 additions and 61 deletions
123
extern/pwrnoise/pwrnoise.c
vendored
123
extern/pwrnoise/pwrnoise.c
vendored
|
@ -40,22 +40,23 @@ void pwrnoise_noise_write(noise_channel_t *chan, uint8_t reg, uint8_t val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrnoise_noise_step(noise_channel_t *chan) {
|
void pwrnoise_noise_step(noise_channel_t *chan, uint16_t cycles) {
|
||||||
chan->octave_counter++;
|
if (!chan->enable) chan->out_latch = 0;
|
||||||
if (chan->enable && !(((chan->octave_counter - 1) >> chan->octave) & 0x0001) && ((chan->octave_counter >> chan->octave) & 0x0001)) {
|
|
||||||
if ((++chan->period_counter) == 4096) {
|
chan->octave_counter += cycles;
|
||||||
|
if (chan->enable && (cycles > 2 || !(((chan->octave_counter - 1) >> chan->octave) & 0x0001) && ((chan->octave_counter >> chan->octave) & 0x0001))) {
|
||||||
|
chan->period_counter += (cycles >> (chan->octave + 1));
|
||||||
|
if (cycles == 1) ++chan->period_counter;
|
||||||
|
|
||||||
|
if (chan->period_counter >= 4096) {
|
||||||
chan->prev = (uint8_t)(chan->lfsr >> 15);
|
chan->prev = (uint8_t)(chan->lfsr >> 15);
|
||||||
uint16_t in = ((chan->lfsr >> chan->tapa) ^ (chan->tapb_enable ? (chan->lfsr >> chan->tapb) : 0)) & 0x0001;
|
uint16_t in = ((chan->lfsr >> chan->tapa) ^ (chan->tapb_enable ? (chan->lfsr >> chan->tapb) : 0)) & 0x0001;
|
||||||
chan->lfsr = (chan->lfsr << 1) | in;
|
chan->lfsr = (chan->lfsr << 1) | in;
|
||||||
chan->period_counter = chan->period;
|
chan->period_counter = chan->period + (chan->period_counter - 4096);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t out = chan->prev;
|
chan->out_latch = (chan->prev != 0) ? chan->vol : 0;
|
||||||
if (!chan->enable) out = 0;
|
|
||||||
else if (out != 0) out = chan->vol;
|
|
||||||
|
|
||||||
chan->out_latch = out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrnoise_slope_write(slope_channel_t *chan, uint8_t reg, uint8_t val) {
|
void pwrnoise_slope_write(slope_channel_t *chan, uint8_t reg, uint8_t val) {
|
||||||
|
@ -96,9 +97,18 @@ void pwrnoise_slope_write(slope_channel_t *chan, uint8_t reg, uint8_t val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrnoise_slope_step(slope_channel_t *chan, bool force_zero) {
|
void pwrnoise_slope_step(slope_channel_t *chan, uint16_t cycles, bool force_zero) {
|
||||||
if (chan->enable && !((chan->octave_counter++ >> chan->octave) & 0x0001) && ((chan->octave_counter >> chan->octave) & 0x0001)) {
|
if (!chan->enable) {
|
||||||
if ((++chan->period_counter) == 4096) {
|
chan->out_latch = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan->octave_counter += cycles;
|
||||||
|
if (chan->enable && (cycles > 2 || !(((chan->octave_counter - 1) >> chan->octave) & 0x0001) && ((chan->octave_counter >> chan->octave) & 0x0001))) {
|
||||||
|
chan->period_counter += (cycles >> (chan->octave + 1));
|
||||||
|
if (cycles == 1) ++chan->period_counter;
|
||||||
|
|
||||||
|
if (chan->period_counter >= 4096) {
|
||||||
if (!chan->portion) {
|
if (!chan->portion) {
|
||||||
if ((chan->flags & 0x02) != 0) chan->accum -= chan->aoffset;
|
if ((chan->flags & 0x02) != 0) chan->accum -= chan->aoffset;
|
||||||
else chan->accum += chan->aoffset;
|
else chan->accum += chan->aoffset;
|
||||||
|
@ -126,48 +136,47 @@ void pwrnoise_slope_step(slope_channel_t *chan, bool force_zero) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chan->period_counter = chan->period;
|
chan->period_counter = chan->period + (chan->period_counter - 4096);
|
||||||
|
|
||||||
|
uint8_t left = chan->accum >> 3;
|
||||||
|
uint8_t right = chan->accum >> 3;
|
||||||
|
|
||||||
|
switch (chan->vol >> 4) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
left >>= 1;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
left >>= 1;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
left >>= 1;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
switch (chan->vol & 0xf) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
right >>= 1;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
right >>= 1;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
right >>= 1;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
left &= (chan->vol >> 4);
|
||||||
|
right &= (chan->vol & 0xf);
|
||||||
|
chan->prev = (left << 4) | right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t left = chan->accum >> 3;
|
chan->out_latch = force_zero ? 0 : chan->prev;
|
||||||
uint8_t right = chan->accum >> 3;
|
|
||||||
|
|
||||||
switch (chan->vol >> 4) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
left >>= 1;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
left >>= 1;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
left >>= 1;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
switch (chan->vol & 0xf) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
right >>= 1;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
right >>= 1;
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
case 7:
|
|
||||||
right >>= 1;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
left &= (chan->vol >> 4);
|
|
||||||
right &= (chan->vol & 0xf);
|
|
||||||
uint8_t out = (left << 4) | right;
|
|
||||||
|
|
||||||
if (!chan->enable || force_zero) out = 0;
|
|
||||||
chan->out_latch = out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrnoise_reset(power_noise_t *pn) {
|
void pwrnoise_reset(power_noise_t *pn) {
|
||||||
|
@ -200,14 +209,14 @@ void pwrnoise_write(power_noise_t *pn, uint8_t reg, uint8_t val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pwrnoise_step(power_noise_t *pn, int16_t *left, int16_t *right) {
|
void pwrnoise_step(power_noise_t *pn, uint16_t cycles, int16_t *left, int16_t *right) {
|
||||||
int32_t final_left, final_right;
|
int32_t final_left, final_right;
|
||||||
|
|
||||||
if ((pn->flags & 0x80) != 0) {
|
if ((pn->flags & 0x80) != 0) {
|
||||||
pwrnoise_noise_step(&pn->n1);
|
pwrnoise_noise_step(&pn->n1, cycles);
|
||||||
pwrnoise_noise_step(&pn->n2);
|
pwrnoise_noise_step(&pn->n2, cycles);
|
||||||
pwrnoise_noise_step(&pn->n3);
|
pwrnoise_noise_step(&pn->n3, cycles);
|
||||||
pwrnoise_slope_step(&pn->s, (pn->n1.am && !(pn->n1.prev)) || (pn->n2.am && !(pn->n2.prev)) || (pn->n3.am && !(pn->n3.prev)));
|
pwrnoise_slope_step(&pn->s, cycles, (pn->n1.am && !(pn->n1.prev)) || (pn->n2.am && !(pn->n2.prev)) || (pn->n3.am && !(pn->n3.prev)));
|
||||||
|
|
||||||
final_left = (pn->n1.out_latch >> 4) + (pn->n2.out_latch >> 4) + (pn->n3.out_latch >> 4) + (pn->s.out_latch >> 4);
|
final_left = (pn->n1.out_latch >> 4) + (pn->n2.out_latch >> 4) + (pn->n3.out_latch >> 4) + (pn->s.out_latch >> 4);
|
||||||
final_right = (pn->n1.out_latch & 0xf) + (pn->n2.out_latch & 0xf) + (pn->n3.out_latch & 0xf) + (pn->s.out_latch & 0xf);
|
final_right = (pn->n1.out_latch & 0xf) + (pn->n2.out_latch & 0xf) + (pn->n3.out_latch & 0xf) + (pn->s.out_latch & 0xf);
|
||||||
|
|
3
extern/pwrnoise/pwrnoise.h
vendored
3
extern/pwrnoise/pwrnoise.h
vendored
|
@ -52,6 +52,7 @@ typedef struct {
|
||||||
uint8_t vol;
|
uint8_t vol;
|
||||||
|
|
||||||
uint8_t out_latch;
|
uint8_t out_latch;
|
||||||
|
uint8_t prev;
|
||||||
} slope_channel_t;
|
} slope_channel_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -66,7 +67,7 @@ typedef struct {
|
||||||
} power_noise_t;
|
} power_noise_t;
|
||||||
|
|
||||||
void pwrnoise_reset(power_noise_t *pn);
|
void pwrnoise_reset(power_noise_t *pn);
|
||||||
void pwrnoise_step(power_noise_t *pn, int16_t *left, int16_t *right);
|
void pwrnoise_step(power_noise_t *pn, uint16_t cycles, int16_t *left, int16_t *right);
|
||||||
void pwrnoise_write(power_noise_t *pn, uint8_t reg, uint8_t val);
|
void pwrnoise_write(power_noise_t *pn, uint8_t reg, uint8_t val);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "powernoise.h"
|
#include "powernoise.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "../../ta-log.h"
|
||||||
#include "furIcons.h"
|
#include "furIcons.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
@ -81,9 +82,7 @@ void DivPlatformPowerNoise::acquire(short** buf, size_t len) {
|
||||||
int16_t left, right;
|
int16_t left, right;
|
||||||
|
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
for(int i = 0; i < 32; i++) {
|
pwrnoise_step(&pn, 32, &left, &right);
|
||||||
pwrnoise_step(&pn, &left, &right);
|
|
||||||
}
|
|
||||||
|
|
||||||
oscBuf[0]->data[oscBuf[0]->needle++]=mapAmp(((pn.n1.out_latch>>1)&0x7)+(pn.n1.out_latch>>5));
|
oscBuf[0]->data[oscBuf[0]->needle++]=mapAmp(((pn.n1.out_latch>>1)&0x7)+(pn.n1.out_latch>>5));
|
||||||
oscBuf[1]->data[oscBuf[1]->needle++]=mapAmp(((pn.n2.out_latch>>1)&0x7)+(pn.n2.out_latch>>5));
|
oscBuf[1]->data[oscBuf[1]->needle++]=mapAmp(((pn.n2.out_latch>>1)&0x7)+(pn.n2.out_latch>>5));
|
||||||
|
|
Loading…
Reference in a new issue