diff options
| author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-08-13 23:08:54 +0900 | 
|---|---|---|
| committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-08-13 23:08:54 +0900 | 
| commit | 5a8af1f670709d6cd28ad5edda223d9ecbc03bc3 (patch) | |
| tree | d8819443b937c49b5a4feb12ad54178d6f79a584 /libopna | |
| parent | 11a5698d68461b91a681f37d66fad5e206969674 (diff) | |
added levelmeter
Diffstat (limited to 'libopna')
| -rw-r--r-- | libopna/opnaadpcm.c | 8 | ||||
| -rw-r--r-- | libopna/opnaadpcm.h | 3 | ||||
| -rw-r--r-- | libopna/opnadrum.c | 7 | ||||
| -rw-r--r-- | libopna/opnadrum.h | 2 | ||||
| -rw-r--r-- | libopna/opnafm.c | 13 | ||||
| -rw-r--r-- | libopna/opnafm.h | 3 | ||||
| -rw-r--r-- | libopna/opnassg.c | 13 | ||||
| -rw-r--r-- | libopna/opnassg.h | 2 | 
8 files changed, 49 insertions, 2 deletions
| diff --git a/libopna/opnaadpcm.c b/libopna/opnaadpcm.c index 68dbae5..361064a 100644 --- a/libopna/opnaadpcm.c +++ b/libopna/opnaadpcm.c @@ -35,6 +35,7 @@ void opna_adpcm_reset(struct opna_adpcm *adpcm) {    adpcm->prev_acc = 0;    adpcm->adpcmd = 127;    adpcm->out = 0; +  leveldata_init(&adpcm->leveldata);  }  static uint32_t addr_conv(const struct opna_adpcm *adpcm, uint16_t a) { @@ -183,8 +184,14 @@ void opna_adpcm_writereg(struct opna_adpcm *adpcm, unsigned reg, unsigned val) {  void opna_adpcm_mix(struct opna_adpcm *adpcm, int16_t *buf, unsigned samples) {    if (!adpcm->ram) return;    if (!(adpcm->control1 & C1_START)) return; +  unsigned level = 0;    for (unsigned i = 0; i < samples; i++) {      adpcm_calc(adpcm); +    { +      int clevel = adpcm->out>>1; +      if (clevel < 0) clevel = -clevel; +      if (((unsigned)clevel) > level) level = clevel; +    }      if (!adpcm->masked) {        int32_t lo = buf[i*2+0];        int32_t ro = buf[i*2+1]; @@ -199,6 +206,7 @@ void opna_adpcm_mix(struct opna_adpcm *adpcm, int16_t *buf, unsigned samples) {      }      if (!(adpcm->control1 & C1_START)) return;    } +  leveldata_update(&adpcm->leveldata, level);  }  void opna_adpcm_set_ram_256k(struct opna_adpcm *adpcm, void *ram) { diff --git a/libopna/opnaadpcm.h b/libopna/opnaadpcm.h index 42033ad..27a0be3 100644 --- a/libopna/opnaadpcm.h +++ b/libopna/opnaadpcm.h @@ -3,6 +3,7 @@  #include <stdint.h>  #include <stdbool.h> +#include "leveldata/leveldata.h"  #ifdef __cplusplus  extern "C" { @@ -24,6 +25,8 @@ struct opna_adpcm {    uint16_t adpcmd;    int16_t out;    bool masked; +  atomic_uint levelvu; +  struct leveldata leveldata;  };  void opna_adpcm_reset(struct opna_adpcm *adpcm); diff --git a/libopna/opnadrum.c b/libopna/opnadrum.c index 1a298af..c3e8d38 100644 --- a/libopna/opnadrum.c +++ b/libopna/opnadrum.c @@ -23,6 +23,7 @@ void opna_drum_reset(struct opna_drum *drum) {      drum->drums[d].level = 0;      drum->drums[d].left = false;      drum->drums[d].right = false; +    leveldata_init(&drum->drums[d].leveldata);    }    drum->total_level = 0;    drum->mask = 0; @@ -81,6 +82,7 @@ void opna_drum_set_rom(struct opna_drum *drum, void *romptr) {  }  void opna_drum_mix(struct opna_drum *drum, int16_t *buf, int samples) { +  unsigned levels[6] = {0};    for (int i = 0; i < samples; i++) {      int32_t lo = buf[i*2+0];      int32_t ro = buf[i*2+1]; @@ -91,6 +93,8 @@ void opna_drum_mix(struct opna_drum *drum, int16_t *buf, int samples) {          unsigned level = (drum->drums[d].level^0x1f) + (drum->total_level^0x3f);          co *= 15 - (level&7);          co >>= 1+(level>>3); +        unsigned outlevel = co > 0 ? co : -co; +        if (outlevel > levels[d]) levels[d] = outlevel;          if (!(drum->mask & (1u << d))) {            if (drum->drums[d].left) lo += co;            if (drum->drums[d].right) ro += co; @@ -109,6 +113,9 @@ void opna_drum_mix(struct opna_drum *drum, int16_t *buf, int samples) {      buf[i*2+0] = lo;      buf[i*2+1] = ro;    } +  for (int d = 0; d < 6; d++) { +    leveldata_update(&drum->drums[d].leveldata, levels[d]); +  }  }  void opna_drum_writereg(struct opna_drum *drum, unsigned reg, unsigned val) { diff --git a/libopna/opnadrum.h b/libopna/opnadrum.h index 79f95a2..7260995 100644 --- a/libopna/opnadrum.h +++ b/libopna/opnadrum.h @@ -3,6 +3,7 @@  #include <stdint.h>  #include <stdbool.h> +#include "leveldata/leveldata.h"  #ifdef __cplusplus  extern "C" { @@ -32,6 +33,7 @@ struct opna_drum {      unsigned level;      bool left;      bool right; +    struct leveldata leveldata;    } drums[6];    unsigned total_level;    int16_t rom_bd[OPNA_ROM_BD_SIZE]; diff --git a/libopna/opnafm.c b/libopna/opnafm.c index 4e86b80..0d57a98 100644 --- a/libopna/opnafm.c +++ b/libopna/opnafm.c @@ -3,6 +3,7 @@  #include "opnatables.h" +  //#include <stdio.h>  #define printf(...) @@ -27,6 +28,7 @@ static void opna_fm_slot_reset(struct opna_fm_slot *slot) {  void opna_fm_chan_reset(struct opna_fm_channel *chan) { +  leveldata_init(&chan->leveldata);    for (int i = 0; i < 4; i++) {      opna_fm_slot_reset(&chan->slot[i]);    } @@ -595,8 +597,6 @@ static int gcd(int a, int b) {    return b;  } - -  void opna_fm_mix(struct opna_fm *fm, int16_t *buf, unsigned samples,                   struct oscillodata *oscillo, unsigned offset) {    if (oscillo) { @@ -620,6 +620,7 @@ void opna_fm_mix(struct opna_fm *fm, int16_t *buf, unsigned samples,        }      }    } +  unsigned level[6] = {0};    for (unsigned i = 0; i < samples; i++) {      if (!fm->env_div3) {        for (int c = 0; c < 6; c++) { @@ -639,6 +640,11 @@ void opna_fm_mix(struct opna_fm *fm, int16_t *buf, unsigned samples,      for (int c = 0; c < 6; c++) {        struct opna_fm_frame o = opna_fm_chanout(&fm->channel[c]); +      unsigned nlevel[2]; +      nlevel[0] = o.data[0] > 0 ? o.data[0] : -o.data[0]; +      nlevel[1] = o.data[1] > 0 ? o.data[1] : -o.data[1]; +      if (nlevel[1] > nlevel[0]) nlevel[0] = nlevel[1]; +      if (nlevel[0] > level[c]) level[c] = nlevel[0];        if (oscillo) oscillo[c].buf[offset+i] = o.data[0] + o.data[1];        // TODO: CSM        if (c == 2 && fm->ch3.mode != CH3_MODE_NORMAL) { @@ -677,4 +683,7 @@ void opna_fm_mix(struct opna_fm *fm, int16_t *buf, unsigned samples,      }      fm->env_div3--;    } +  for (int c = 0; c < 6; c++) { +    leveldata_update(&fm->channel[c].leveldata, level[c]); +  }  } diff --git a/libopna/opnafm.h b/libopna/opnafm.h index 9da143f..359517b 100644 --- a/libopna/opnafm.h +++ b/libopna/opnafm.h @@ -3,6 +3,7 @@  #include <stdint.h>  #include <stdbool.h> +#include "leveldata/leveldata.h"  #ifdef __cplusplus  extern "C" { @@ -64,6 +65,8 @@ struct opna_fm_channel {    uint8_t fb;    uint16_t fnum;    uint8_t blk; +   +  struct leveldata leveldata;  };  struct opna_fm { diff --git a/libopna/opnassg.c b/libopna/opnassg.c index 86d9c9a..d92a8b8 100644 --- a/libopna/opnassg.c +++ b/libopna/opnassg.c @@ -134,6 +134,9 @@ void opna_ssg_resampler_reset(struct opna_ssg_resampler *resampler) {      resampler->buf[i] = 0;    }    resampler->index = 0; +  for (int c = 0; c < 3; c++) { +    leveldata_init(&resampler->leveldata[c]); +  }  }  void opna_ssg_writereg(struct opna_ssg *ssg, unsigned reg, unsigned val) { @@ -286,6 +289,7 @@ void opna_ssg_mix_55466(        }      }    } +  unsigned level[3] = {0};    for (int i = 0; i < samples; i++) {      {        int ssg_samples = ((resampler->index + 9)>>1) - ((resampler->index)>>1); @@ -305,6 +309,12 @@ void opna_ssg_mix_55466(      opna_ssg_sinc_calc_func(resampler->index, resampler->buf, outbuf);      for (int ch = 0; ch < 3; ch++) {        if (oscillo) oscillo[ch].buf[offset+i] = outbuf[ch] >> 15; +      int32_t nlevel = outbuf[ch]; +      nlevel >>= 16; +      nlevel *= 13000; +      nlevel >>= 14; +      if (nlevel < 0) nlevel = -nlevel; +      if (((unsigned)nlevel) > level[ch]) level[ch] = nlevel;        if (!(ssg->mask & (1<<ch))) sample += outbuf[ch] >> 2;      }      sample >>= 16; @@ -322,5 +332,8 @@ void opna_ssg_mix_55466(      buf[i*2+0] = lo;      buf[i*2+1] = ro;    } +  for (int c = 0; c < 3; c++) { +    leveldata_update(&resampler->leveldata[c], level[c]); +  }  }  #undef BUFINDEX diff --git a/libopna/opnassg.h b/libopna/opnassg.h index 8af8429..3077d08 100644 --- a/libopna/opnassg.h +++ b/libopna/opnassg.h @@ -3,6 +3,7 @@  #include <stdint.h>  #include <stdbool.h> +#include "leveldata/leveldata.h"  #ifdef __cplusplus  extern "C" { @@ -35,6 +36,7 @@ struct opna_ssg {  struct opna_ssg_resampler {    int16_t buf[OPNA_SSG_SINCTABLELEN*4 * 2];    unsigned index; +  struct leveldata leveldata[3];  };  void opna_ssg_reset(struct opna_ssg *ssg); | 
