aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-09-12 21:24:16 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-09-12 21:24:16 +0900
commit8435fa6d33704c5170635f9a53c17142f69117e4 (patch)
tree509815a4150bac919b6411bbba90f7bddf2b7d18
parent676390c58c6367bcfeda901456d637939645b78e (diff)
fmdsp: pacc: add level, fft
-rw-r--r--fmdsp/fmdsp-pacc.c358
-rw-r--r--fmdsp/fmdsp-pacc.h4
-rw-r--r--sdl/main.c22
-rw-r--r--sdl/osx/Makefile2
-rw-r--r--sdl/unix/Makefile4
-rw-r--r--sdl/win/Makefile2
6 files changed, 385 insertions, 7 deletions
diff --git a/fmdsp/fmdsp-pacc.c b/fmdsp/fmdsp-pacc.c
index 815e323..bf76693 100644
--- a/fmdsp/fmdsp-pacc.c
+++ b/fmdsp/fmdsp-pacc.c
@@ -4,12 +4,15 @@
#include "fmdriver/fmdriver.h"
#include "libopna/opna.h"
#include "version.h"
+#include "fft/fft.h"
#include "fmdsp_sprites.h"
#include <stdlib.h>
#include <string.h>
#include "fmdsp_platform_info.h"
+#include <math.h>
+
enum {
FADEDELTA = 16,
};
@@ -105,10 +108,11 @@ static const uint8_t track_disp_table_13[] = {
struct fmdsp_pacc {
struct pacc_ctx *pc;
struct pacc_vtable pacc;
- struct pacc_tex *tex_font, *tex_checker, *tex_key_left, *tex_key_right, *tex_key_mask, *tex_key_bg, *tex_num, *tex_dt_sign, *tex_solid, *tex_vertical, *tex_horizontal, *tex_logo, *tex_ver, *tex_text, *tex_tri, *tex_curl_left, *tex_curl_right, *tex_play, *tex_stop, *tex_pause, *tex_fade, *tex_ff, *tex_rew, *tex_floppy, *tex_circle;
- struct pacc_buf *buf_font_7, *buf_font_2, *buf_font_2_d, *buf_font_1, *buf_font_1_d, *buf_checker, *buf_key_left, *buf_key_right, *buf_key_mask, *buf_key_mask_sub, *buf_key_bg, *buf_num, *buf_dt_sign, *buf_solid_2, *buf_solid_2_d, *buf_solid_3, *buf_solid_3_d, *buf_solid_7, *buf_solid_7_d, *buf_vertical_2, *buf_vertical_3, *buf_vertical_7, *buf_logo, *buf_ver, *buf_text, *buf_tri, *buf_tri_7, *buf_curl_left, *buf_curl_right, *buf_play, *buf_stop, *buf_pause, *buf_fade, *buf_ff, *buf_rew, *buf_floppy, *buf_circle;
+ struct pacc_tex *tex_font, *tex_checker, *tex_key_left, *tex_key_right, *tex_key_mask, *tex_key_bg, *tex_num, *tex_dt_sign, *tex_solid, *tex_vertical, *tex_horizontal, *tex_logo, *tex_ver, *tex_text, *tex_tri, *tex_curl_left, *tex_curl_right, *tex_play, *tex_stop, *tex_pause, *tex_fade, *tex_ff, *tex_rew, *tex_floppy, *tex_circle, *tex_panpot;
+ struct pacc_buf *buf_font_7, *buf_font_2, *buf_font_2_d, *buf_font_1, *buf_font_1_d, *buf_checker, *buf_checker_1, *buf_key_left, *buf_key_right, *buf_key_mask, *buf_key_mask_sub, *buf_key_bg, *buf_num, *buf_dt_sign, *buf_solid_2, *buf_solid_2_d, *buf_solid_3, *buf_solid_3_d, *buf_solid_7, *buf_solid_7_d, *buf_vertical_2, *buf_vertical_3, *buf_vertical_7, *buf_horizontal_2_d, *buf_horizontal_3, *buf_horizontal_7_d, *buf_logo, *buf_ver, *buf_text, *buf_tri, *buf_tri_7, *buf_curl_left, *buf_curl_right, *buf_play, *buf_stop, *buf_pause, *buf_fade, *buf_ff, *buf_rew, *buf_floppy, *buf_circle, *buf_panpot_1_d, *buf_panpot_5_d;
struct opna *opna;
struct fmdriver_work *work;
+ struct fmplayer_fft_input_data *fftin;
uint8_t curr_palette[FMDSP_PALETTE_COLORS*3];
uint8_t target_palette[FMDSP_PALETTE_COLORS*3];
enum fmdsp_left_mode lmode;
@@ -119,6 +123,12 @@ struct fmdsp_pacc {
int cpuusage;
int fps;
uint64_t framecnt;
+ uint8_t fftdata[FFTDISPLEN];
+ uint8_t fftcnt[FFTDISPLEN];
+ uint8_t fftdropdiv[FFTDISPLEN];
+ uint8_t leveldata[FMDSP_LEVEL_COUNT];
+ uint8_t levelcnt[FMDSP_LEVEL_COUNT];
+ uint8_t leveldropdiv[FMDSP_LEVEL_COUNT];
};
static struct pacc_tex *tex_from_font(
@@ -148,6 +158,7 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {
fp->pacc.buf_delete(fp->buf_font_2_d);
fp->pacc.buf_delete(fp->buf_font_7);
fp->pacc.buf_delete(fp->buf_checker);
+ fp->pacc.buf_delete(fp->buf_checker_1);
fp->pacc.buf_delete(fp->buf_key_left);
fp->pacc.buf_delete(fp->buf_key_right);
fp->pacc.buf_delete(fp->buf_key_mask);
@@ -164,6 +175,9 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {
fp->pacc.buf_delete(fp->buf_vertical_2);
fp->pacc.buf_delete(fp->buf_vertical_3);
fp->pacc.buf_delete(fp->buf_vertical_7);
+ fp->pacc.buf_delete(fp->buf_horizontal_2_d);
+ fp->pacc.buf_delete(fp->buf_horizontal_3);
+ fp->pacc.buf_delete(fp->buf_horizontal_7_d);
fp->pacc.buf_delete(fp->buf_logo);
fp->pacc.buf_delete(fp->buf_ver);
fp->pacc.buf_delete(fp->buf_text);
@@ -179,6 +193,8 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {
fp->pacc.buf_delete(fp->buf_rew);
fp->pacc.buf_delete(fp->buf_floppy);
fp->pacc.buf_delete(fp->buf_circle);
+ fp->pacc.buf_delete(fp->buf_panpot_1_d);
+ fp->pacc.buf_delete(fp->buf_panpot_5_d);
fp->pacc.tex_delete(fp->tex_font);
fp->pacc.tex_delete(fp->tex_checker);
fp->pacc.tex_delete(fp->tex_key_left);
@@ -204,6 +220,7 @@ void fmdsp_pacc_release(struct fmdsp_pacc *fp) {
fp->pacc.tex_delete(fp->tex_rew);
fp->pacc.tex_delete(fp->tex_floppy);
fp->pacc.tex_delete(fp->tex_circle);
+ fp->pacc.tex_delete(fp->tex_panpot);
}
free(fp);
}
@@ -510,6 +527,8 @@ struct fmdsp_pacc *fmdsp_pacc_init(
if (!fp->tex_floppy) goto err;
fp->tex_circle = fp->pacc.gen_tex(fp->pc, CIRCLE_W, CIRCLE_H*9);
if (!fp->tex_circle) goto err;
+ fp->tex_panpot = fp->pacc.gen_tex(fp->pc, PANPOT_W, PANPOT_H*6);
+ if (!fp->tex_panpot) goto err;
uint8_t *buf;
buf = fp->pacc.tex_lock(fp->tex_checker);
@@ -571,6 +590,9 @@ struct fmdsp_pacc *fmdsp_pacc_init(
buf = fp->pacc.tex_lock(fp->tex_floppy);
memcpy(buf, s_floppy, FLOPPY_W*FLOPPY_H);
fp->pacc.tex_unlock(fp->tex_floppy);
+ buf = fp->pacc.tex_lock(fp->tex_panpot);
+ memcpy(buf, s_panpot, PANPOT_W*PANPOT_H*6);
+ fp->pacc.tex_unlock(fp->tex_panpot);
buf = fp->pacc.tex_lock(fp->tex_solid);
buf[0] = 1;
fp->pacc.tex_unlock(fp->tex_solid);
@@ -633,6 +655,8 @@ struct fmdsp_pacc *fmdsp_pacc_init(
if (!fp->buf_font_7) goto err;
fp->buf_checker = fp->pacc.gen_buf(fp->pc, fp->tex_checker, pacc_buf_mode_static);
if (!fp->buf_checker) goto err;
+ fp->buf_checker_1 = fp->pacc.gen_buf(fp->pc, fp->tex_checker, pacc_buf_mode_static);
+ if (!fp->buf_checker_1) goto err;
fp->buf_key_left = fp->pacc.gen_buf(fp->pc, fp->tex_key_left, pacc_buf_mode_static);
if (!fp->buf_key_left) goto err;
fp->buf_key_right = fp->pacc.gen_buf(fp->pc, fp->tex_key_right, pacc_buf_mode_static);
@@ -665,6 +689,12 @@ struct fmdsp_pacc *fmdsp_pacc_init(
if (!fp->buf_vertical_3) goto err;
fp->buf_vertical_7 = fp->pacc.gen_buf(fp->pc, fp->tex_vertical, pacc_buf_mode_stream);
if (!fp->buf_vertical_7) goto err;
+ fp->buf_horizontal_2_d = fp->pacc.gen_buf(fp->pc, fp->tex_horizontal, pacc_buf_mode_stream);
+ if (!fp->buf_horizontal_2_d) goto err;
+ fp->buf_horizontal_3 = fp->pacc.gen_buf(fp->pc, fp->tex_horizontal, pacc_buf_mode_static);
+ if (!fp->buf_horizontal_3) goto err;
+ fp->buf_horizontal_7_d = fp->pacc.gen_buf(fp->pc, fp->tex_horizontal, pacc_buf_mode_stream);
+ if (!fp->buf_horizontal_7_d) goto err;
fp->buf_logo = fp->pacc.gen_buf(fp->pc, fp->tex_logo, pacc_buf_mode_static);
if (!fp->buf_logo) goto err;
fp->buf_ver = fp->pacc.gen_buf(fp->pc, fp->tex_ver, pacc_buf_mode_static);
@@ -695,6 +725,10 @@ struct fmdsp_pacc *fmdsp_pacc_init(
if (!fp->buf_floppy) goto err;
fp->buf_circle = fp->pacc.gen_buf(fp->pc, fp->tex_circle, pacc_buf_mode_stream);
if (!fp->buf_circle) goto err;
+ fp->buf_panpot_1_d = fp->pacc.gen_buf(fp->pc, fp->tex_panpot, pacc_buf_mode_stream);
+ if (!fp->buf_panpot_1_d) goto err;
+ fp->buf_panpot_5_d = fp->pacc.gen_buf(fp->pc, fp->tex_panpot, pacc_buf_mode_stream);
+ if (!fp->buf_panpot_5_d) goto err;
fp->pacc.buf_rect_off(fp->pc, fp->buf_checker, 1, CHECKER_Y, PC98_W-1, CHECKER_H, 1, 0);
fp->pacc.buf_rect(fp->pc, fp->buf_checker, 0, CHECKER_Y+2, 1, CHECKER_H-4);
@@ -946,6 +980,144 @@ static void init_default(struct fmdsp_pacc *fp) {
fp->pc, fp->buf_solid_7,
352+142, 70-2, 1, 1);
+ // fft
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_3,
+ SPECTRUM_X+i*4, SPECTRUM_Y-62,
+ 3, 64);
+ }
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ SPECTRUM_X+197, SPECTRUM_Y-71,
+ "SPECTRUM");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ SPECTRUM_X+241, SPECTRUM_Y-71,
+ "ANAL");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ SPECTRUM_X+260, SPECTRUM_Y-71,
+ "YzER");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X-24, SPECTRUM_Y+1,
+ "FREQ");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+36, SPECTRUM_Y+1,
+ "250");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+83, SPECTRUM_Y+1,
+ "500");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+133, SPECTRUM_Y+1,
+ "1");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+133+6, SPECTRUM_Y+1,
+ "k");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+183, SPECTRUM_Y+1,
+ "2k");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ SPECTRUM_X+230, SPECTRUM_Y+1,
+ "4k");
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_solid_2,
+ SPECTRUM_X-2, SPECTRUM_Y-62, 1, 63);
+ for (int i = 0; i < 32; i++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_solid_2,
+ SPECTRUM_X-3 - (((i % 4) == 3) ? 1 : 0), SPECTRUM_Y-62+2*i,
+ ((i % 4) == 3) ? 2 : 1, 1);
+ }
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+1, SPECTRUM_Y+4, 34, 1);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+52, SPECTRUM_Y+4, 30, 1);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+99, SPECTRUM_Y+4, 34, 1);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+144, SPECTRUM_Y+4, 38, 1);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+193, SPECTRUM_Y+4, 36, 1);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_checker_1,
+ SPECTRUM_X+240, SPECTRUM_Y+4, 40, 1);
+ // level
+ for (int c = 0; c < FMDSP_LEVEL_COUNT; c++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_3,
+ LEVEL_X + LEVEL_W*c, LEVEL_Y,
+ LEVEL_DISP_W, 64);
+ }
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ LEVEL_TEXT_X+5, LEVEL_TEXT_Y,
+ "ON");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ LEVEL_TEXT_X, LEVEL_TEXT_Y+8,
+ "PAN");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ LEVEL_TEXT_X-5, LEVEL_TEXT_Y+16,
+ "PROG");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1,
+ LEVEL_TEXT_X, LEVEL_TEXT_Y+23,
+ "KEY");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*0, LEVEL_TRACK_Y,
+ "FM1");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*3, LEVEL_TRACK_Y,
+ "FM4");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*6, LEVEL_TRACK_Y,
+ "SSG");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*9, LEVEL_TRACK_Y,
+ "RHY");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*10, LEVEL_TRACK_Y,
+ "ADP");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X+LEVEL_W*11, LEVEL_TRACK_Y,
+ "PPZ");
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_solid_2,
+ LEVEL_X-2, LEVEL_Y, 1, 63);
+ for (int i = 0; i < 32; i++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_solid_2,
+ LEVEL_X-3-((i % 4) == 3), LEVEL_Y+i*2,
+ ((i % 4) == 3) + 1, 1);
+ }
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X-9, LEVEL_Y-1,
+ "0");
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_7,
+ LEVEL_X-19, LEVEL_Y+56,
+ "-48");
}
static void update_default(struct fmdsp_pacc *fp) {
@@ -1069,9 +1241,176 @@ static void update_default(struct fmdsp_pacc *fp) {
fp->pc, fp->buf_circle,
CIRCLE_X, CIRCLE_Y, CIRCLE_W, CIRCLE_H,
0, CIRCLE_H*clock);
+
+ // fft
+ struct fmplayer_fft_disp_data ddata = {0};
+ fft_calc(&ddata, fp->fftin);
+ for (int x = 0; x < FFTDISPLEN; x++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_2_d,
+ SPECTRUM_X+x*4, SPECTRUM_Y-62+(32-ddata.buf[x])*2, 3, ddata.buf[x]*2);
+ }
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ if (fp->fftdata[i] <= ddata.buf[i]) {
+ fp->fftdata[i] = ddata.buf[i];
+ fp->fftcnt[i] = 30;
+ } else {
+ if (fp->fftcnt[i]) {
+ fp->fftcnt[i]--;
+ } else {
+ if (fp->fftdata[i]) {
+ if (fp->fftdropdiv[i]) {
+ fp->fftdropdiv[i]--;
+ } else {
+ static const uint8_t divtab[16] = {
+ 32, 16, 8, 8, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
+ };
+ fp->fftdropdiv[i] = divtab[fp->fftdata[i] / 2];
+ fp->fftdata[i]--;
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < FFTDISPLEN; i++) {
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_7_d,
+ SPECTRUM_X+i*4, SPECTRUM_Y-fp->fftdata[i]*2, 3, 1);
+ }
+ // level
+ struct {
+ unsigned level;
+ int t;
+ bool masked;
+ uint8_t pan;
+ uint8_t prog;
+ uint8_t key;
+ bool playing;
+ } levels[FMDSP_LEVEL_COUNT] = {0};
+ for (int c = 0; c < 6; c++) {
+ levels[c].level = leveldata_read(&fp->opna->fm.channel[c].leveldata);
+ static const int table[4] = {5, 4, 0, 2};
+ levels[c].pan = table[fp->opna->fm.lselect[c]*2 + fp->opna->fm.rselect[c]];
+ }
+ levels[0].t = FMDRIVER_TRACK_FM_1;
+ levels[1].t = FMDRIVER_TRACK_FM_2;
+ levels[2].t = FMDRIVER_TRACK_FM_3;
+ levels[3].t = FMDRIVER_TRACK_FM_4;
+ levels[4].t = FMDRIVER_TRACK_FM_5;
+ levels[5].t = FMDRIVER_TRACK_FM_6;
+
+ for (int c = 0; c < 3; c++) {
+ levels[6+c].level = leveldata_read(&fp->opna->resampler.leveldata[c]);
+ levels[6+c].t = FMDRIVER_TRACK_SSG_1+c;
+ levels[6+c].pan = 2;
+ }
+ {
+ unsigned dl = 0;
+ for (int d = 0; d < 6; d++) {
+ unsigned l = leveldata_read(&fp->opna->drum.drums[d].leveldata);
+ if (l > dl) dl = l;
+ }
+ levels[9].level = dl;
+ levels[9].pan = 2;
+ }
+ levels[10].level = leveldata_read(&fp->opna->adpcm.leveldata);
+ levels[10].t = FMDRIVER_TRACK_ADPCM;
+ {
+ static const int table[4] = {5, 4, 0, 2};
+ int ind = 0;
+ if (fp->opna->adpcm.control2 & 0x80) ind |= 2;
+ if (fp->opna->adpcm.control2 & 0x40) ind |= 1;
+ levels[10].pan = table[ind];
+ }
+ for (int p = 0; p < 8; p++) {
+ levels[11+p].pan = 5;
+ levels[11+p].t = FMDRIVER_TRACK_PPZ8_1+p;
+ }
+ if (fp->work->ppz8) {
+ for (int p = 0; p < 8; p++) {
+ levels[11+p].level = leveldata_read(&fp->work->ppz8->channel[p].leveldata);
+ static const int table[10] = {5, 0, 1, 1, 1, 2, 3, 3, 3, 4};
+ levels[11+p].pan = table[fp->work->ppz8->channel[p].pan];
+ }
+ }
+ for (int c = 0; c < FMDSP_LEVEL_COUNT; c++) {
+ levels[c].masked = c == 9 ? fp->masked_rhythm : fp->masked[levels[c].t];
+ levels[c].prog = fp->work->track_status[levels[c].t].tonenum;
+ levels[c].key = fp->work->track_status[levels[c].t].key;
+ levels[c].playing = fp->work->track_status[levels[c].t].playing;
+ if (fp->work->track_status[levels[c].t].info == FMDRIVER_TRACK_INFO_PDZF ||
+ fp->work->track_status[levels[c].t].info == FMDRIVER_TRACK_INFO_PPZ8) {
+ levels[c].playing = false;
+ }
+ if (!levels[c].playing) levels[c].pan = 5;
+ }
+
+ for (int c = 0; c < FMDSP_LEVEL_COUNT; c++) {
+ unsigned level = levels[c].level;
+ unsigned llevel = 0;
+ if (level) {
+ float db = 20.0f * log10f((float)level / (1<<15));
+ float fllevel = (db / 48.0f + 1.0f) * 32.0f;
+ if (fllevel > 0.0f) llevel = fllevel;
+ }
+
+ if (fp->leveldata[c] <= llevel) {
+ fp->leveldata[c] = llevel;
+ fp->levelcnt[c] = 30;
+ } else {
+ if (fp->levelcnt[c]) {
+ fp->levelcnt[c]--;
+ } else {
+ if (fp->leveldata[c]) {
+ if (fp->leveldropdiv[c]) {
+ fp->leveldropdiv[c]--;
+ } else {
+ static const uint8_t divtab[16] = {
+ 32, 16, 8, 8, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
+ };
+ fp->leveldropdiv[c] = divtab[fp->leveldata[c] / 2];
+ fp->leveldata[c]--;
+ }
+ }
+ }
+ }
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_2_d,
+ LEVEL_X + LEVEL_W*c, LEVEL_Y + (64-llevel*2),
+ LEVEL_DISP_W, llevel*2);
+ fp->pacc.buf_rect(
+ fp->pc, fp->buf_horizontal_7_d,
+ LEVEL_X + LEVEL_W*c, LEVEL_Y + (62-fp->leveldata[c]*2),
+ LEVEL_DISP_W, 1);
+ fp->pacc.buf_rect_off(
+ fp->pc, levels[c].masked ? fp->buf_panpot_5_d : fp->buf_panpot_1_d,
+ LEVEL_X + LEVEL_W*c-1, PANPOT_Y,
+ PANPOT_W, PANPOT_H,
+ 0, PANPOT_H*levels[c].pan);
+ if (c != 9) {
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1_d,
+ LEVEL_X + LEVEL_W*c, LEVEL_PROG_Y,
+ "%03d", levels[c].prog);
+ }
+ uint8_t oct = levels[c].key >> 4;
+ uint8_t n = levels[c].key & 0xf;
+ if (c != 9 && levels[c].playing && n < 12) {
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1_d,
+ LEVEL_X + LEVEL_W*c, LEVEL_KEY_Y,
+ "%03d", oct*12 + n);
+ } else {
+ fp->pacc.buf_printf(
+ fp->pc, fp->buf_font_1_d,
+ LEVEL_X + LEVEL_W*c, LEVEL_KEY_Y,
+ "---");
+ }
+ }
}
static void mode_update(struct fmdsp_pacc *fp) {
+ fp->pacc.buf_clear(fp->buf_horizontal_3);
fp->pacc.buf_clear(fp->buf_font_1);
fp->pacc.buf_clear(fp->buf_font_2);
fp->pacc.buf_clear(fp->buf_font_7);
@@ -1087,6 +1426,7 @@ static void mode_update(struct fmdsp_pacc *fp) {
fp->pacc.buf_clear(fp->buf_tri_7);
fp->pacc.buf_clear(fp->buf_tri);
fp->pacc.buf_clear(fp->buf_checker);
+ fp->pacc.buf_clear(fp->buf_checker_1);
fp->pacc.buf_clear(fp->buf_curl_left);
fp->pacc.buf_clear(fp->buf_curl_right);
fp->pacc.buf_clear(fp->buf_play);
@@ -1166,7 +1506,11 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {
fp->pacc.buf_clear(fp->buf_vertical_2);
fp->pacc.buf_clear(fp->buf_vertical_3);
fp->pacc.buf_clear(fp->buf_vertical_7);
+ fp->pacc.buf_clear(fp->buf_horizontal_2_d);
+ fp->pacc.buf_clear(fp->buf_horizontal_7_d);
fp->pacc.buf_clear(fp->buf_circle);
+ fp->pacc.buf_clear(fp->buf_panpot_1_d);
+ fp->pacc.buf_clear(fp->buf_panpot_5_d);
unsigned mask = 0;
if (fp->opna) {
mask = opna_get_mask(fp->opna);
@@ -1232,22 +1576,29 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {
fp->pacc.draw(fp->pc, fp->buf_font_1, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_font_1_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_dt_sign, pacc_mode_color);
+ fp->pacc.draw(fp->pc, fp->buf_checker_1, pacc_mode_color);
+ fp->pacc.draw(fp->pc, fp->buf_panpot_1_d, pacc_mode_color);
fp->pacc.color(fp->pc, 3);
fp->pacc.draw(fp->pc, fp->buf_solid_3, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_solid_3_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_vertical_3, pacc_mode_color);
+ fp->pacc.draw(fp->pc, fp->buf_horizontal_3, pacc_mode_color);
fp->pacc.color(fp->pc, 2);
fp->pacc.draw(fp->pc, fp->buf_font_2, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_font_2_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_solid_2, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_solid_2_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_vertical_2, pacc_mode_color);
+ fp->pacc.draw(fp->pc, fp->buf_horizontal_2_d, pacc_mode_color);
+ fp->pacc.color(fp->pc, 5);
+ fp->pacc.draw(fp->pc, fp->buf_panpot_5_d, pacc_mode_color);
fp->pacc.color(fp->pc, 7);
fp->pacc.draw(fp->pc, fp->buf_font_7, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_solid_7, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_solid_7_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_vertical_7, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_tri_7, pacc_mode_color);
+ fp->pacc.draw(fp->pc, fp->buf_horizontal_7_d, pacc_mode_color);
fp->pacc.draw(fp->pc, fp->buf_tri, pacc_mode_copy);
fp->pacc.draw(fp->pc, fp->buf_num, pacc_mode_copy);
fp->pacc.draw(fp->pc, fp->buf_checker, pacc_mode_copy);
@@ -1289,9 +1640,10 @@ void fmdsp_pacc_render(struct fmdsp_pacc *fp) {
fp->framecnt++;
}
-void fmdsp_pacc_set(struct fmdsp_pacc *fp, struct fmdriver_work *work, struct opna *opna) {
+void fmdsp_pacc_set(struct fmdsp_pacc *fp, struct fmdriver_work *work, struct opna *opna, struct fmplayer_fft_input_data *idata) {
fp->work = work;
fp->opna = opna;
+ fp->fftin = idata;
}
void fmdsp_pacc_palette(struct fmdsp_pacc *fp, int p) {
diff --git a/fmdsp/fmdsp-pacc.h b/fmdsp/fmdsp-pacc.h
index fb19b79..992a8eb 100644
--- a/fmdsp/fmdsp-pacc.h
+++ b/fmdsp/fmdsp-pacc.h
@@ -6,9 +6,11 @@ struct pacc_ctx;
struct pacc_vtable;
struct fmdriver_work work;
struct opna opna;
+struct fmplayer_fft_input_data;
enum {
FMDSP_PALETTE_COLORS = 10,
+ FMDSP_LEVEL_COUNT = 19,
};
enum {
@@ -35,7 +37,7 @@ enum fmdsp_right_mode {
struct fmdsp_pacc *fmdsp_pacc_init(
struct pacc_ctx *pc, const struct pacc_vtable *vtable);
-void fmdsp_pacc_set(struct fmdsp_pacc *pacc, struct fmdriver_work *work, struct opna *opna);
+void fmdsp_pacc_set(struct fmdsp_pacc *pacc, struct fmdriver_work *work, struct opna *opna, struct fmplayer_fft_input_data *fftin);
void fmdsp_pacc_release(struct fmdsp_pacc *fp);
void fmdsp_pacc_render(struct fmdsp_pacc *fp);
diff --git a/sdl/main.c b/sdl/main.c
index 410ed88..39ead1b 100644
--- a/sdl/main.c
+++ b/sdl/main.c
@@ -1,5 +1,6 @@
#include <SDL.h>
#include <stdbool.h>
+#include <stdatomic.h>
#include "pacc/pacc.h"
#include "fmdsp/fmdsp-pacc.h"
#include "libopna/opna.h"
@@ -7,6 +8,7 @@
#include "fmdriver/fmdriver.h"
#include "common/fmplayer_file.h"
#include "common/fmplayer_common.h"
+#include "fft/fft.h"
bool loadgl(void);
@@ -20,19 +22,29 @@ static struct {
struct opna_timer timer;
struct fmdriver_work work;
struct fmplayer_file *fmfile;
+ struct fmplayer_fft_data fftdata;
+ struct fmplayer_fft_input_data fftin;
const char *currpath;
SDL_Window *win;
SDL_AudioDeviceID adev;
struct ppz8 ppz8;
char adpcmram[OPNA_ADPCM_RAM_SIZE];
struct fmdsp_pacc *fp;
-} g;
+ atomic_flag fftdata_flag;
+} g = {
+ .fftdata_flag = ATOMIC_FLAG_INIT,
+};
static void audiocb(void *ptr, Uint8 *bufptr, int len) {
int frames = len / (sizeof(int16_t)*2);
int16_t *buf = (int16_t *)bufptr;
memset(buf, 0, len);
opna_timer_mix(&g.timer, buf, frames);
+ if (!atomic_flag_test_and_set_explicit(
+ &g.fftdata_flag, memory_order_acquire)) {
+ fft_write(&g.fftdata, buf, frames);
+ atomic_flag_clear_explicit(&g.fftdata_flag, memory_order_release);
+ }
}
static void openfile(const char *path) {
@@ -57,6 +69,7 @@ static void openfile(const char *path) {
int main(int argc, char **argv) {
if (__builtin_cpu_supports("sse2")) opna_ssg_sinc_calc_func = opna_ssg_sinc_calc_sse2;
+ fft_init_table();
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
SDL_Log("Cannot initialize SDL\n");
return 1;
@@ -140,7 +153,7 @@ int main(int argc, char **argv) {
SDL_Quit();
return 1;
}
- fmdsp_pacc_set(g.fp, &g.work, &g.opna);
+ fmdsp_pacc_set(g.fp, &g.work, &g.opna, &g.fftin);
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
@@ -206,6 +219,11 @@ int main(int argc, char **argv) {
}
}
}
+ if (!atomic_flag_test_and_set_explicit(
+ &g.fftdata_flag, memory_order_acquire)) {
+ memcpy(&g.fftin.fdata, &g.fftdata, sizeof(g.fftdata));
+ atomic_flag_clear_explicit(&g.fftdata_flag, memory_order_release);
+ }
fmdsp_pacc_render(g.fp);
SDL_GL_SwapWindow(g.win);
}
diff --git a/sdl/osx/Makefile b/sdl/osx/Makefile
index 73bea70..8c17c7d 100644
--- a/sdl/osx/Makefile
+++ b/sdl/osx/Makefile
@@ -4,6 +4,7 @@ vpath %.c ../../fmdsp
vpath %.c ../../libopna
vpath %.c ../../common
vpath %.c ../../fmdriver
+vpath %.c ../../fft
XCRUN:=xcrun --sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
CC:=$(XCRUN) cc
OBJS:=main.o
@@ -12,6 +13,7 @@ OBJS+=fmdsp-pacc.o font_fmdsp_small.o fmdsp_platform_unix.o
OBJS+=opna.o opnafm.o opnassg.o opnadrum.o opnaadpcm.o opnatimer.o opnassg-sinc-c.o opnassg-sinc-sse2.o
OBJS+=fmdriver_pmd.o fmdriver_fmp.o ppz8.o fmdriver_common.o
OBJS+=fmplayer_file.o fmplayer_work_opna.o fmplayer_file_unix.o fmplayer_drumrom_unix.o
+OBJS+=fft.o
TARGET:=fmplayersdl
CFLAGS:=-Wall -Wextra -O2 -g
CFLAGS+=-DPACC_GL_3
diff --git a/sdl/unix/Makefile b/sdl/unix/Makefile
index 9786031..ea22098 100644
--- a/sdl/unix/Makefile
+++ b/sdl/unix/Makefile
@@ -4,6 +4,7 @@ vpath %.c ../../fmdsp
vpath %.c ../../libopna
vpath %.c ../../common
vpath %.c ../../fmdriver
+vpath %.c ../../fft
SDLCONFIG:=sdl2-config
OBJS:=main.o
OBJS+=pacc-gl.o
@@ -11,6 +12,7 @@ OBJS+=fmdsp-pacc.o font_fmdsp_small.o fmdsp_platform_unix.o
OBJS+=opna.o opnafm.o opnassg.o opnadrum.o opnaadpcm.o opnatimer.o opnassg-sinc-c.o opnassg-sinc-sse2.o
OBJS+=fmdriver_pmd.o fmdriver_fmp.o ppz8.o fmdriver_common.o
OBJS+=fmplayer_file.o fmplayer_work_opna.o fmplayer_file_unix.o fmplayer_drumrom_unix.o
+OBJS+=fft.o
TARGET:=fmplayersdl
CFLAGS:=-Wall -Wextra -O2 -g
@@ -19,7 +21,7 @@ CFLAGS+=-DPACC_GL_3
#CFLAGS+=-DPACC_GL_ES -DPACC_GL_3
CFLAGS+=-I.. -I../..
CFLAGS+=$(shell $(SDLCONFIG) --cflags)
-LIBS:=-lGL
+LIBS:=-lGL -lm
LIBS+=$(shell $(SDLCONFIG) --libs)
$(TARGET): $(OBJS)
diff --git a/sdl/win/Makefile b/sdl/win/Makefile
index e804dfc..0f63d19 100644
--- a/sdl/win/Makefile
+++ b/sdl/win/Makefile
@@ -4,6 +4,7 @@ vpath %.c ../../fmdsp
vpath %.c ../../libopna
vpath %.c ../../common
vpath %.c ../../fmdriver
+vpath %.c ../../fft
SDLCONFIG:=i686-w64-mingw32-sdl2-config
CC:=i686-w64-mingw32-gcc
OBJS:=main.o
@@ -12,6 +13,7 @@ OBJS+=fmdsp-pacc.o font_fmdsp_small.o fmdsp_platform_win.o
OBJS+=opna.o opnafm.o opnassg.o opnadrum.o opnaadpcm.o opnatimer.o opnassg-sinc-c.o opnassg-sinc-sse2.o
OBJS+=fmdriver_pmd.o fmdriver_fmp.o ppz8.o fmdriver_common.o
OBJS+=fmplayer_file.o fmplayer_work_opna.o fmplayer_file_win.o fmplayer_drumrom_win.o
+OBJS+=fft.o
TARGET:=fmplayersdl.exe
CFLAGS:=-Wall -Wextra -O2